Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

some more wire formatting improvements #989

Merged
merged 1 commit into from
Dec 20, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
127 changes: 111 additions & 16 deletions projects/Benchmarks/WireFormatting/DataTypeSerialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,83 @@ public class DataTypeSerialization
public virtual void SetUp() { }
}

public class DateTypeArraySerialization : DataTypeSerialization
public class DataTypeFieldSerialization : DataTypeSerialization
{
readonly List<object> _emptyArray = new List<object>();
Memory<byte> _emptyArrayBuffer;
Memory<byte> _populatedArrayBuffer;
List<object> _array;
private readonly object _intObject = 5;
private readonly string _shortString = new string('x', 100);
private readonly byte[] _byteArray = new byte[0];
private readonly Dictionary<string, object> _emptyDictionary = new Dictionary<string, object>();
private readonly BinaryTableValue _binaryTableValue = new BinaryTableValue(new byte[0]);

private Memory<byte> _fieldStringBuffer;
private Memory<byte> _fieldIntBuffer;
private Memory<byte> _fieldNullBuffer;
private Memory<byte> _fieldArrayBuffer;
private Memory<byte> _fieldDictBuffer;
private Memory<byte> _fieldBinaryTableValueBuffer;

public override void SetUp()
{
_fieldNullBuffer = new byte[WireFormatting.GetFieldValueByteCount(null)];
WireFormatting.WriteFieldValue(_fieldNullBuffer.Span, null);
_fieldIntBuffer = new byte[WireFormatting.GetFieldValueByteCount(_intObject)];
WireFormatting.WriteFieldValue(_fieldIntBuffer.Span, _intObject);
_fieldStringBuffer = new byte[WireFormatting.GetFieldValueByteCount(_shortString)];
WireFormatting.WriteFieldValue(_fieldStringBuffer.Span, _shortString);
_fieldArrayBuffer = new byte[WireFormatting.GetFieldValueByteCount(_byteArray)];
WireFormatting.WriteFieldValue(_fieldArrayBuffer.Span, _byteArray);
_fieldDictBuffer = new byte[WireFormatting.GetFieldValueByteCount(_emptyDictionary)];
WireFormatting.WriteFieldValue(_fieldDictBuffer.Span, _emptyDictionary);
_fieldBinaryTableValueBuffer = new byte[WireFormatting.GetFieldValueByteCount(_binaryTableValue)];
WireFormatting.WriteFieldValue(_fieldBinaryTableValueBuffer.Span, _binaryTableValue);
}

[Benchmark]
public object NullRead() => WireFormatting.ReadFieldValue(_fieldNullBuffer.Span, out int _);
[Benchmark]
public object IntRead() => WireFormatting.ReadFieldValue(_fieldIntBuffer.Span, out int _);
[Benchmark]
public object StringRead() => WireFormatting.ReadFieldValue(_fieldStringBuffer.Span, out int _);
[Benchmark]
public object ArrayRead() => WireFormatting.ReadFieldValue(_fieldArrayBuffer.Span, out int _);
[Benchmark]
public object DictRead() => WireFormatting.ReadFieldValue(_fieldDictBuffer.Span, out int _);
[Benchmark]
public object BinaryTableValueRead() => WireFormatting.ReadFieldValue(_fieldBinaryTableValueBuffer.Span, out int _);

[Benchmark]
public int NullWrite() => WireFormatting.WriteFieldValue(_buffer.Span,null);
[Benchmark]
public int IntWrite() => WireFormatting.WriteFieldValue(_buffer.Span, _intObject);
[Benchmark]
public int StringWrite() => WireFormatting.WriteFieldValue(_buffer.Span, _shortString);
[Benchmark]
public int ArrayWrite() => WireFormatting.WriteFieldValue(_buffer.Span, _byteArray);
[Benchmark]
public int DictWrite() => WireFormatting.WriteFieldValue(_buffer.Span, _emptyDictionary);
[Benchmark]
public int BinaryTableValueWrite() => WireFormatting.WriteFieldValue(_buffer.Span, _binaryTableValue);

[Benchmark]
public int NullGetSize() => WireFormatting.GetFieldValueByteCount(null);
[Benchmark]
public int IntGetSize() => WireFormatting.GetFieldValueByteCount(_intObject);
[Benchmark]
public int StringGetSize() => WireFormatting.GetFieldValueByteCount(_shortString);
[Benchmark]
public int ArrayGetSize() => WireFormatting.GetFieldValueByteCount(_byteArray);
[Benchmark]
public int DictGetSize() => WireFormatting.GetFieldValueByteCount(_emptyDictionary);
[Benchmark]
public int BinaryTableValueGetSize() => WireFormatting.GetFieldValueByteCount(_binaryTableValue);
}

public class DataTypeArraySerialization : DataTypeSerialization
{
private readonly List<object> _emptyArray = new List<object>();
private Memory<byte> _emptyArrayBuffer;
private Memory<byte> _populatedArrayBuffer;
private List<object> _array;

public override void SetUp()
{
Expand All @@ -49,14 +120,20 @@ public override void SetUp()

[Benchmark]
public int ArrayWritePopulated() => WireFormatting.WriteArray(_buffer.Span, _array);

[Benchmark]
public int ArrayGetSizeEmpty() => WireFormatting.GetArrayByteCount(_emptyArray);

[Benchmark]
public int ArrayGetSizePopulated() => WireFormatting.GetArrayByteCount(_array);
}

public class DataTypeTableSerialization : DataTypeSerialization
{
IDictionary<string, object> _emptyDict = new Dictionary<string, object>();
IDictionary<string, object> _populatedDict;
Memory<byte> _emptyDictionaryBuffer;
Memory<byte> _populatedDictionaryBuffer;
private IDictionary<string, object> _emptyDict = new Dictionary<string, object>();
private IDictionary<string, object> _populatedDict;
private Memory<byte> _emptyDictionaryBuffer;
private Memory<byte> _populatedDictionaryBuffer;

public override void SetUp()
{
Expand All @@ -67,7 +144,7 @@ public override void SetUp()
{ "uint", 1234u },
{ "decimal", 12.34m },
{ "timestamp", _timestamp },
{ "fieldtable", new Dictionary<string, object>(){ { "test", "test" } } },
{ "fieldtable", new Dictionary<string, object>{ { "test", "test" } } },
{ "fieldarray", new List<object> { "longstring", 1234, 12.34m, _timestamp } }
};

Expand All @@ -89,13 +166,19 @@ public override void SetUp()

[Benchmark]
public int TableWritePopulated() => WireFormatting.WriteTable(_buffer.Span, _populatedDict);

[Benchmark]
public int TableGetSizeEmpty() => WireFormatting.GetTableByteCount(_emptyDict);

[Benchmark]
public int TableGetSizePopulated() => WireFormatting.GetTableByteCount(_populatedDict);
}

public class DataTypeLongStringSerialization : DataTypeSerialization
{
readonly string _longString = new string('X', 4096);
readonly Memory<byte> _emptyLongStringBuffer = GenerateLongStringBuffer(string.Empty);
readonly Memory<byte> _populatedLongStringBuffer = GenerateLongStringBuffer(new string('X', 4096));
private readonly string _longString = new string('X', 4096);
private readonly Memory<byte> _emptyLongStringBuffer = GenerateLongStringBuffer(string.Empty);
private readonly Memory<byte> _populatedLongStringBuffer = GenerateLongStringBuffer(new string('X', 4096));

[Benchmark]
public int LongstrReadEmpty() => WireFormatting.ReadLongstr(_emptyLongStringBuffer.Span, out _);
Expand All @@ -109,6 +192,12 @@ public class DataTypeLongStringSerialization : DataTypeSerialization
[Benchmark]
public int LongstrWritePopulated() => WireFormatting.WriteLongstr(_buffer.Span, _longString);

[Benchmark]
public int LongstrGetSizeEmpty() => WireFormatting.GetFieldValueByteCount(string.Empty);

[Benchmark]
public int LongstrGetSizePopulated() => WireFormatting.GetFieldValueByteCount(_longString);

private static byte[] GenerateLongStringBuffer(string val)
{
byte[] _buffer = new byte[5 + Encoding.UTF8.GetByteCount(val)];
Expand All @@ -119,9 +208,9 @@ private static byte[] GenerateLongStringBuffer(string val)

public class DataTypeShortStringSerialization : DataTypeSerialization
{
readonly string _shortString = new string('X', 255);
readonly Memory<byte> _emptyShortStringBuffer = GenerateStringBuffer(string.Empty);
readonly Memory<byte> _populatedShortStringBuffer = GenerateStringBuffer(new string('X', 255));
private readonly string _shortString = new string('X', 255);
private readonly Memory<byte> _emptyShortStringBuffer = GenerateStringBuffer(string.Empty);
private readonly Memory<byte> _populatedShortStringBuffer = GenerateStringBuffer(new string('X', 255));

[Benchmark]
public int ShortstrReadEmpty() => WireFormatting.ReadShortstr(_emptyShortStringBuffer.Span, out _);
Expand All @@ -135,6 +224,12 @@ public class DataTypeShortStringSerialization : DataTypeSerialization
[Benchmark]
public int ShortstrWritePopulated() => WireFormatting.WriteShortstr(_buffer.Span, _shortString);

[Benchmark]
public int ShortstrGetSizeEmpty() => WireFormatting.GetByteCount(string.Empty);

[Benchmark]
public int ShortstrGetSizePopulated() => WireFormatting.GetByteCount(_shortString);

private static byte[] GenerateStringBuffer(string val)
{
byte[] _buffer = new byte[2 + Encoding.UTF8.GetByteCount(val)];
Expand Down
6 changes: 6 additions & 0 deletions projects/Benchmarks/WireFormatting/MethodSerialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@ public class MethodBasicDeliver : MethodSerializationBase

[Benchmark]
public int BasicDeliverWrite() => _basicDeliver.WriteArgumentsTo(_buffer.Span);

[Benchmark]
public int BasicDeliverSize() => _basicDeliver.GetRequiredBufferSize();
}

public class MethodChannelClose : MethodSerializationBase
Expand All @@ -64,5 +67,8 @@ public class MethodBasicProperties : MethodSerializationBase

[Benchmark]
public int BasicPropertiesWrite() => _basicProperties.WritePropertiesTo(_buffer.Span);

[Benchmark]
public int BasicDeliverSize() => _basicProperties.GetRequiredPayloadBufferSize();
}
}
28 changes: 25 additions & 3 deletions projects/Benchmarks/WireFormatting/PrimitivesSerialization.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,25 @@ public class PrimitivesBase
public virtual void Setup() { }
}

public class PrimitivesBool : PrimitivesBase
{
public override void Setup() => WireFormatting.WriteBits(_buffer.Span, true, false, true, false, true);

[Benchmark]
public int BoolRead2() => WireFormatting.ReadBits(_buffer.Span, out bool _, out bool _);

[Benchmark]
public int BoolRead5() => WireFormatting.ReadBits(_buffer.Span, out bool _, out bool _, out bool _, out bool _, out bool _);

[Benchmark]
[Arguments(true, false)]
public int BoolWrite2(bool param1, bool param2) => WireFormatting.WriteBits(_buffer.Span, param1, param2);

[Benchmark]
[Arguments(true, false)]
public int BoolWrite5(bool param1, bool param2) => WireFormatting.WriteBits(_buffer.Span, param1, param2, param1, param2, param1);
}

public class PrimitivesDecimal : PrimitivesBase
{
public override void Setup() => WireFormatting.WriteDecimal(_buffer.Span, 123.45m);
Expand All @@ -36,7 +55,8 @@ public class PrimitivesLong : PrimitivesBase
public int LongRead() => WireFormatting.ReadLong(_buffer.Span, out _);

[Benchmark]
public int LongWrite() => WireFormatting.WriteLong(_buffer.Span, 12345u);
[Arguments(12345u)]
public int LongWrite(uint value) => WireFormatting.WriteLong(_buffer.Span, value);
}

public class PrimitivesLonglong : PrimitivesBase
Expand All @@ -47,7 +67,8 @@ public class PrimitivesLonglong : PrimitivesBase
public int LonglongRead() => WireFormatting.ReadLonglong(_buffer.Span, out _);

[Benchmark]
public int LonglongWrite() => WireFormatting.WriteLonglong(_buffer.Span, 12345ul);
[Arguments(12345ul)]
public int LonglongWrite(ulong value) => WireFormatting.WriteLonglong(_buffer.Span, value);
}

public class PrimitivesShort : PrimitivesBase
Expand All @@ -58,7 +79,8 @@ public class PrimitivesShort : PrimitivesBase
public int ShortRead() => WireFormatting.ReadShort(_buffer.Span, out _);

[Benchmark]
public int ShortWrite() => WireFormatting.WriteShort(_buffer.Span, 12345);
[Arguments(12345)]
public int ShortWrite(ushort value) => WireFormatting.WriteShort(_buffer.Span, value);
}

public class PrimitivesTimestamp : PrimitivesBase
Expand Down
Loading