Skip to content

Commit 2f407cd

Browse files
author
Stefán J. Sigurðarson
committed
Optimizing bitfield writes.
Hardcoding redundant buffer-length checks since we precalculate the required buffer sizes before writing.
1 parent 846e590 commit 2f407cd

33 files changed

+146
-150
lines changed

projects/Benchmarks/WireFormatting/DataTypeSerialization.cs

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -39,17 +39,17 @@ public class DataTypeFieldSerialization : DataTypeSerialization
3939
public override void SetUp()
4040
{
4141
_fieldNullBuffer = new byte[WireFormatting.GetFieldValueByteCount(null)];
42-
WireFormatting.WriteFieldValue(ref _fieldNullBuffer.Span.GetStart(), null, _fieldNullBuffer.Length);
42+
WireFormatting.WriteFieldValue(ref _fieldNullBuffer.Span.GetStart(), null);
4343
_fieldIntBuffer = new byte[WireFormatting.GetFieldValueByteCount(_intObject)];
44-
WireFormatting.WriteFieldValue(ref _fieldIntBuffer.Span.GetStart(), _intObject, _fieldIntBuffer.Length);
44+
WireFormatting.WriteFieldValue(ref _fieldIntBuffer.Span.GetStart(), _intObject);
4545
_fieldStringBuffer = new byte[WireFormatting.GetFieldValueByteCount(_shortString)];
46-
WireFormatting.WriteFieldValue(ref _fieldStringBuffer.Span.GetStart(), _shortString, _fieldStringBuffer.Length);
46+
WireFormatting.WriteFieldValue(ref _fieldStringBuffer.Span.GetStart(), _shortString);
4747
_fieldArrayBuffer = new byte[WireFormatting.GetFieldValueByteCount(_byteArray)];
48-
WireFormatting.WriteFieldValue(ref _fieldArrayBuffer.Span.GetStart(), _byteArray, _fieldArrayBuffer.Length);
48+
WireFormatting.WriteFieldValue(ref _fieldArrayBuffer.Span.GetStart(), _byteArray);
4949
_fieldDictBuffer = new byte[WireFormatting.GetFieldValueByteCount(_emptyDictionary)];
50-
WireFormatting.WriteFieldValue(ref _fieldDictBuffer.Span.GetStart(), _emptyDictionary, _fieldDictBuffer.Length);
50+
WireFormatting.WriteFieldValue(ref _fieldDictBuffer.Span.GetStart(), _emptyDictionary);
5151
_fieldBinaryTableValueBuffer = new byte[WireFormatting.GetFieldValueByteCount(_binaryTableValue)];
52-
WireFormatting.WriteFieldValue(ref _fieldBinaryTableValueBuffer.Span.GetStart(), _binaryTableValue, _fieldBinaryTableValueBuffer.Length);
52+
WireFormatting.WriteFieldValue(ref _fieldBinaryTableValueBuffer.Span.GetStart(), _binaryTableValue);
5353
}
5454

5555
[Benchmark]
@@ -65,17 +65,17 @@ public override void SetUp()
6565
[Benchmark]
6666
public object BinaryTableValueRead() => WireFormatting.ReadFieldValue(_fieldBinaryTableValueBuffer.Span, out int _);
6767
[Benchmark]
68-
public int NullWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), null, _buffer.Length);
68+
public int NullWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), null);
6969
[Benchmark]
70-
public int IntWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _intObject, _buffer.Length);
70+
public int IntWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _intObject);
7171
[Benchmark]
72-
public int StringWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _shortString, _buffer.Length);
72+
public int StringWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _shortString);
7373
[Benchmark]
74-
public int ArrayWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _byteArray, _buffer.Length);
74+
public int ArrayWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _byteArray);
7575
[Benchmark]
76-
public int DictWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _emptyDictionary, _buffer.Length);
76+
public int DictWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _emptyDictionary);
7777
[Benchmark]
78-
public int BinaryTableValueWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _binaryTableValue, _buffer.Length);
78+
public int BinaryTableValueWrite() => WireFormatting.WriteFieldValue(ref _buffer.Span.GetStart(), _binaryTableValue);
7979
[Benchmark]
8080
public int NullGetSize() => WireFormatting.GetFieldValueByteCount(null);
8181
[Benchmark]
@@ -101,10 +101,10 @@ public override void SetUp()
101101
{
102102
_array = new List<object> { "longstring", 1234, 12.34m, _timestamp };
103103
_emptyArrayBuffer = new byte[WireFormatting.GetArrayByteCount(_emptyArray)];
104-
WireFormatting.WriteArray(ref _emptyArrayBuffer.Span.GetStart(), _emptyArray, _emptyArrayBuffer.Length);
104+
WireFormatting.WriteArray(ref _emptyArrayBuffer.Span.GetStart(), _emptyArray);
105105

106106
_populatedArrayBuffer = new byte[WireFormatting.GetArrayByteCount(_array)];
107-
WireFormatting.WriteArray(ref _populatedArrayBuffer.Span.GetStart(), _array, _populatedArrayBuffer.Length);
107+
WireFormatting.WriteArray(ref _populatedArrayBuffer.Span.GetStart(), _array);
108108
}
109109

110110
[Benchmark]
@@ -114,10 +114,10 @@ public override void SetUp()
114114
public IList ArrayReadPopulated() => WireFormatting.ReadArray(_populatedArrayBuffer.Span, out _);
115115

116116
[Benchmark]
117-
public int ArrayWriteEmpty() => WireFormatting.WriteArray(ref _buffer.Span.GetStart(), _emptyArray, _buffer.Length);
117+
public int ArrayWriteEmpty() => WireFormatting.WriteArray(ref _buffer.Span.GetStart(), _emptyArray);
118118

119119
[Benchmark]
120-
public int ArrayWritePopulated() => WireFormatting.WriteArray(ref _buffer.Span.GetStart(), _array, _buffer.Length);
120+
public int ArrayWritePopulated() => WireFormatting.WriteArray(ref _buffer.Span.GetStart(), _array);
121121

122122
[Benchmark]
123123
public int ArrayGetSizeEmpty() => WireFormatting.GetArrayByteCount(_emptyArray);
@@ -147,10 +147,10 @@ public override void SetUp()
147147
};
148148

149149
_emptyDictionaryBuffer = new byte[WireFormatting.GetTableByteCount(_emptyDict)];
150-
WireFormatting.WriteTable(ref _emptyDictionaryBuffer.Span.GetStart(), _emptyDict, _emptyDictionaryBuffer.Length);
150+
WireFormatting.WriteTable(ref _emptyDictionaryBuffer.Span.GetStart(), _emptyDict);
151151

152152
_populatedDictionaryBuffer = new byte[WireFormatting.GetTableByteCount(_populatedDict)];
153-
WireFormatting.WriteTable(ref _populatedDictionaryBuffer.Span.GetStart(), _populatedDict, _populatedDictionaryBuffer.Length);
153+
WireFormatting.WriteTable(ref _populatedDictionaryBuffer.Span.GetStart(), _populatedDict);
154154
}
155155

156156
[Benchmark]
@@ -160,10 +160,10 @@ public override void SetUp()
160160
public int TableReadPopulated() => WireFormatting.ReadDictionary(_populatedDictionaryBuffer.Span, out _);
161161

162162
[Benchmark]
163-
public int TableWriteEmpty() => WireFormatting.WriteTable(ref _buffer.Span.GetStart(), _emptyDict, _buffer.Length);
163+
public int TableWriteEmpty() => WireFormatting.WriteTable(ref _buffer.Span.GetStart(), _emptyDict);
164164

165165
[Benchmark]
166-
public int TableWritePopulated() => WireFormatting.WriteTable(ref _buffer.Span.GetStart(), _populatedDict, _buffer.Length);
166+
public int TableWritePopulated() => WireFormatting.WriteTable(ref _buffer.Span.GetStart(), _populatedDict);
167167

168168
[Benchmark]
169169
public int TableGetSizeEmpty() => WireFormatting.GetTableByteCount(_emptyDict);
@@ -185,10 +185,10 @@ public class DataTypeLongStringSerialization : DataTypeSerialization
185185
public int LongstrReadPopulated() => WireFormatting.ReadLongstr(_populatedLongStringBuffer.Span, out _);
186186

187187
[Benchmark]
188-
public int LongstrWriteEmpty() => WireFormatting.WriteLongstr(ref _buffer.Span.GetStart(), string.Empty, _buffer.Length);
188+
public int LongstrWriteEmpty() => WireFormatting.WriteLongstr(ref _buffer.Span.GetStart(), string.Empty);
189189

190190
[Benchmark]
191-
public int LongstrWritePopulated() => WireFormatting.WriteLongstr(ref _buffer.Span.GetStart(), _longString, _buffer.Length);
191+
public int LongstrWritePopulated() => WireFormatting.WriteLongstr(ref _buffer.Span.GetStart(), _longString);
192192

193193
[Benchmark]
194194
public int LongstrGetSizeEmpty() => WireFormatting.GetFieldValueByteCount(string.Empty);
@@ -199,7 +199,7 @@ public class DataTypeLongStringSerialization : DataTypeSerialization
199199
private static byte[] GenerateLongStringBuffer(string val)
200200
{
201201
byte[] _buffer = new byte[5 + Encoding.UTF8.GetByteCount(val)];
202-
WireFormatting.WriteLongstr(ref _buffer.GetStart(), val, _buffer.Length);
202+
WireFormatting.WriteLongstr(ref _buffer.GetStart(), val);
203203
return _buffer;
204204
}
205205
}
@@ -217,10 +217,10 @@ public class DataTypeShortStringSerialization : DataTypeSerialization
217217
public int ShortstrReadPopulated() => WireFormatting.ReadShortstr(_populatedShortStringBuffer.Span, out _);
218218

219219
[Benchmark]
220-
public int ShortstrWriteEmpty() => WireFormatting.WriteShortstr(ref _buffer.Span.GetStart(), string.Empty, _buffer.Length);
220+
public int ShortstrWriteEmpty() => WireFormatting.WriteShortstr(ref _buffer.Span.GetStart(), string.Empty);
221221

222222
[Benchmark]
223-
public int ShortstrWritePopulated() => WireFormatting.WriteShortstr(ref _buffer.Span.GetStart(), _shortString, _buffer.Length);
223+
public int ShortstrWritePopulated() => WireFormatting.WriteShortstr(ref _buffer.Span.GetStart(), _shortString);
224224

225225
[Benchmark]
226226
public int ShortstrGetSizeEmpty() => WireFormatting.GetByteCount(string.Empty);
@@ -231,7 +231,7 @@ public class DataTypeShortStringSerialization : DataTypeSerialization
231231
private static byte[] GenerateStringBuffer(string val)
232232
{
233233
byte[] _buffer = new byte[2 + Encoding.UTF8.GetByteCount(val)];
234-
WireFormatting.WriteShortstr(ref _buffer.GetStart(), val, _buffer.Length);
234+
WireFormatting.WriteShortstr(ref _buffer.GetStart(), val);
235235
return _buffer;
236236
}
237237
}

projects/Benchmarks/WireFormatting/MethodSerialization.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ public class MethodBasicDeliver : MethodSerializationBase
3939
public override void SetUp()
4040
{
4141
int length = _buffer.Length;
42-
int offset = Client.Impl.WireFormatting.WriteShortstr(ref _buffer.Span.GetStart(), string.Empty, length);
42+
int offset = Client.Impl.WireFormatting.WriteShortstr(ref _buffer.Span.GetStart(), string.Empty);
4343
offset += Client.Impl.WireFormatting.WriteLonglong(ref _buffer.Span.GetOffset(offset), 0);
4444
offset += Client.Impl.WireFormatting.WriteBits(ref _buffer.Span.GetOffset(offset), false);
45-
offset += Client.Impl.WireFormatting.WriteShortstr(ref _buffer.Span.GetOffset(offset), string.Empty, length - offset);
46-
Client.Impl.WireFormatting.WriteShortstr(ref _buffer.Span.GetOffset(offset), string.Empty, length - offset);
45+
offset += Client.Impl.WireFormatting.WriteShortstr(ref _buffer.Span.GetOffset(offset), string.Empty);
46+
Client.Impl.WireFormatting.WriteShortstr(ref _buffer.Span.GetOffset(offset), string.Empty);
4747
}
4848

4949
[Benchmark]

projects/RabbitMQ.Client/client/framing/BasicCancel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ public BasicCancel(ReadOnlySpan<byte> span)
6262

6363
public override int WriteArgumentsTo(Span<byte> span)
6464
{
65-
int offset = WireFormatting.WriteShortstr(ref span.GetStart(), _consumerTag, span.Length);
65+
int offset = WireFormatting.WriteShortstr(ref span.GetStart(), _consumerTag);
6666
return offset + WireFormatting.WriteBits(ref span.GetOffset(offset), _nowait);
6767
}
6868

projects/RabbitMQ.Client/client/framing/BasicCancelOk.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@
3030
//---------------------------------------------------------------------------
3131

3232
using System;
33-
using System.Text;
33+
3434
using RabbitMQ.Client.client.framing;
3535
using RabbitMQ.Client.Impl;
3636

@@ -59,7 +59,7 @@ public BasicCancelOk(ReadOnlySpan<byte> span)
5959

6060
public override int WriteArgumentsTo(Span<byte> span)
6161
{
62-
return WireFormatting.WriteShortstr(ref span.GetStart(), _consumerTag, span.Length);
62+
return WireFormatting.WriteShortstr(ref span.GetStart(), _consumerTag);
6363
}
6464

6565
public override int GetRequiredBufferSize()

projects/RabbitMQ.Client/client/framing/BasicConsume.cs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,12 +79,11 @@ public BasicConsume(ReadOnlySpan<byte> span)
7979

8080
public override int WriteArgumentsTo(Span<byte> span)
8181
{
82-
int length = span.Length;
8382
int offset = WireFormatting.WriteShort(ref span.GetStart(), default);
84-
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _queue, length - offset);
85-
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _consumerTag, length - offset);
83+
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _queue);
84+
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _consumerTag);
8685
offset += WireFormatting.WriteBits(ref span.GetOffset(offset), _noLocal, _noAck, _exclusive, _nowait);
87-
return offset + WireFormatting.WriteTable(ref span.GetOffset(offset), _arguments, length - offset);
86+
return offset + WireFormatting.WriteTable(ref span.GetOffset(offset), _arguments);
8887
}
8988

9089
public override int GetRequiredBufferSize()

projects/RabbitMQ.Client/client/framing/BasicConsumeOk.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ public BasicConsumeOk(ReadOnlySpan<byte> span)
5959

6060
public override int WriteArgumentsTo(Span<byte> span)
6161
{
62-
return WireFormatting.WriteShortstr(ref span.GetStart(), _consumerTag, span.Length);
62+
return WireFormatting.WriteShortstr(ref span.GetStart(), _consumerTag);
6363
}
6464

6565
public override int GetRequiredBufferSize()

projects/RabbitMQ.Client/client/framing/BasicDeliver.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,11 +72,11 @@ public BasicDeliver(ReadOnlySpan<byte> span)
7272
public override int WriteArgumentsTo(Span<byte> span)
7373
{
7474
int length = span.Length;
75-
int offset = WireFormatting.WriteShortstr(ref span.GetStart(), _consumerTag, length);
75+
int offset = WireFormatting.WriteShortstr(ref span.GetStart(), _consumerTag);
7676
offset += WireFormatting.WriteLonglong(ref span.GetOffset(offset), _deliveryTag);
7777
offset += WireFormatting.WriteBits(ref span.GetOffset(offset), _redelivered);
78-
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _exchange, length - offset);
79-
return offset + WireFormatting.WriteShortstr(ref span.GetOffset(offset), _routingKey, length - offset);
78+
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _exchange);
79+
return offset + WireFormatting.WriteShortstr(ref span.GetOffset(offset), _routingKey);
8080
}
8181

8282
public override int GetRequiredBufferSize()

projects/RabbitMQ.Client/client/framing/BasicGet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ public BasicGet(ReadOnlySpan<byte> span)
6666
public override int WriteArgumentsTo(Span<byte> span)
6767
{
6868
int offset = WireFormatting.WriteShort(ref span.GetStart(), default);
69-
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _queue, span.Length - offset);
69+
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _queue);
7070
return offset + WireFormatting.WriteBits(ref span.GetOffset(offset), _noAck);
7171
}
7272

projects/RabbitMQ.Client/client/framing/BasicGetOk.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,8 +74,8 @@ public override int WriteArgumentsTo(Span<byte> span)
7474
int length = span.Length;
7575
int offset = WireFormatting.WriteLonglong(ref span.GetStart(), _deliveryTag);
7676
offset += WireFormatting.WriteBits(ref span.GetOffset(offset), _redelivered);
77-
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _exchange, length - offset);
78-
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _routingKey, length - offset);
77+
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _exchange);
78+
offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _routingKey);
7979
return offset + WireFormatting.WriteLong(ref span.GetOffset(offset), _messageCount);
8080
}
8181

projects/RabbitMQ.Client/client/framing/BasicProperties.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -241,20 +241,20 @@ internal override int WritePropertiesTo(Span<byte> span)
241241
IsContentTypePresent(), IsContentEncodingPresent(), IsHeadersPresent(), IsDeliveryModePresent(), IsPriorityPresent(),
242242
IsCorrelationIdPresent(), IsReplyToPresent(), IsExpirationPresent(), IsMessageIdPresent(), IsTimestampPresent(),
243243
IsTypePresent(), IsUserIdPresent(), IsAppIdPresent(), IsClusterIdPresent());
244-
if (IsContentTypePresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _contentType, length - offset); }
245-
if (IsContentEncodingPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _contentEncoding, length - offset); }
246-
if (IsHeadersPresent()) { offset += WireFormatting.WriteTable(ref span.GetOffset(offset), _headers, length - offset); }
244+
if (IsContentTypePresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _contentType); }
245+
if (IsContentEncodingPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _contentEncoding); }
246+
if (IsHeadersPresent()) { offset += WireFormatting.WriteTable(ref span.GetOffset(offset), _headers); }
247247
if (IsDeliveryModePresent()) { span[offset++] = _deliveryMode; }
248248
if (IsPriorityPresent()) { span[offset++] = _priority; }
249-
if (IsCorrelationIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _correlationId, length - offset); }
250-
if (IsReplyToPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _replyTo, length - offset); }
251-
if (IsExpirationPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _expiration, length - offset); }
252-
if (IsMessageIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _messageId, length - offset); }
249+
if (IsCorrelationIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _correlationId); }
250+
if (IsReplyToPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _replyTo); }
251+
if (IsExpirationPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _expiration); }
252+
if (IsMessageIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _messageId); }
253253
if (IsTimestampPresent()) { offset += WireFormatting.WriteTimestamp(ref span.GetOffset(offset), _timestamp); }
254-
if (IsTypePresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _type, length - offset); }
255-
if (IsUserIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _userId, length - offset); }
256-
if (IsAppIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _appId, length - offset); }
257-
if (IsClusterIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _clusterId, length - offset); }
254+
if (IsTypePresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _type); }
255+
if (IsUserIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _userId); }
256+
if (IsAppIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _appId); }
257+
if (IsClusterIdPresent()) { offset += WireFormatting.WriteShortstr(ref span.GetOffset(offset), _clusterId); }
258258
return offset;
259259
}
260260

0 commit comments

Comments
 (0)