Skip to content

Commit 656fcaa

Browse files
authored
replace seq.Slice(offset) with seq[offset..] (#182)
Improve the publish - replace seq.Slice(offset) with seq[offset..] - Add AggressiveInlining to the main send functions - Add AggressiveInlining to write functions - Tune the performance test increasing the messages buffer Signed-off-by: Gabriele Santomaggio <G.santomaggio@gmail.com>
1 parent 6bf2a73 commit 656fcaa

File tree

13 files changed

+98
-90
lines changed

13 files changed

+98
-90
lines changed

RabbitMQ.Stream.Client.PerfTest/Program.fs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ let main argv =
3737
let producerConfig = RawProducerConfig(streamName,
3838
Reference = null,
3939
MaxInFlight = 10000,
40+
MessagesBufferSize = 10000,
4041
ConfirmHandler = fun c -> confirmed <- confirmed + 1)
4142
let! producer = system.CreateRawProducer producerConfig
4243
//make producer available to metrics async

RabbitMQ.Stream.Client/AMQP/AmqpWireFormattingRead.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,7 @@ internal static int ReadString(ref SequenceReader<byte> reader, out string value
182182
case FormatCode.Sym32:
183183
case FormatCode.Str32:
184184
offset += WireFormatting.ReadInt32(ref reader, out var len);
185-
Span<byte> tempSpan32 = len <= 64 ? stackalloc byte[len] : new byte[len];
185+
var tempSpan32 = len <= 64 ? stackalloc byte[len] : new byte[len];
186186
reader.TryCopyTo(tempSpan32);
187187
reader.Advance(len);
188188
value = Encoding.UTF8.GetString(tempSpan32);

RabbitMQ.Stream.Client/AMQP/AmqpWireFormattingWrite.cs

Lines changed: 35 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -41,16 +41,16 @@ private static int WriteString(Span<byte> seq, string value)
4141
// Str8
4242
if (len <= byte.MaxValue)
4343
{
44-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Str8);
45-
offset += WireFormatting.WriteByte(seq.Slice(offset), (byte)len);
46-
offset += s_encoding.GetBytes(value, seq.Slice(offset));
44+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Str8);
45+
offset += WireFormatting.WriteByte(seq[offset..], (byte)len);
46+
offset += s_encoding.GetBytes(value, seq[offset..]);
4747
return offset;
4848
}
4949

5050
// Str32
51-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Str32);
52-
offset += WireFormatting.WriteInt32(seq.Slice(offset), len);
53-
offset += s_encoding.GetBytes(value, seq.Slice(offset));
51+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Str32);
52+
offset += WireFormatting.WriteInt32(seq[offset..], len);
53+
offset += s_encoding.GetBytes(value, seq[offset..]);
5454
return offset;
5555
}
5656

@@ -64,13 +64,13 @@ private static int WriteUInt64(Span<byte> seq, ulong value)
6464
var offset = 0;
6565
if (value < 256)
6666
{
67-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.SmallUlong);
68-
offset += WireFormatting.WriteByte(seq.Slice(offset), (byte)value);
67+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.SmallUlong);
68+
offset += WireFormatting.WriteByte(seq[offset..], (byte)value);
6969
return offset;
7070
}
7171

72-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Ulong);
73-
offset += WireFormatting.WriteUInt64(seq.Slice(offset), value);
72+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Ulong);
73+
offset += WireFormatting.WriteUInt64(seq[offset..], value);
7474
return offset;
7575
}
7676

@@ -83,13 +83,13 @@ private static int WriteUInt(Span<byte> seq, uint value)
8383
case 0:
8484
return WireFormatting.WriteByte(seq, FormatCode.Uint0);
8585
case < 256:
86-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.SmallUint);
87-
offset += WireFormatting.WriteByte(seq.Slice(offset), (byte)value);
86+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.SmallUint);
87+
offset += WireFormatting.WriteByte(seq[offset..], (byte)value);
8888
return offset;
8989
}
9090

91-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Uint);
92-
offset += WireFormatting.WriteUInt32(seq.Slice(offset), value);
91+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Uint);
92+
offset += WireFormatting.WriteUInt32(seq[offset..], value);
9393
return offset;
9494
}
9595

@@ -98,14 +98,14 @@ private static int WriteInt(Span<byte> seq, int value)
9898
var offset = 0;
9999
if (value is < 128 and >= -128)
100100
{
101-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Smallint);
102-
offset += WireFormatting.WriteByte(seq.Slice(offset), (byte)value);
101+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Smallint);
102+
offset += WireFormatting.WriteByte(seq[offset..], (byte)value);
103103

104104
return offset;
105105
}
106106

107-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Int);
108-
offset += WireFormatting.WriteInt32(seq.Slice(offset), value);
107+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Int);
108+
offset += WireFormatting.WriteInt32(seq[offset..], value);
109109
return offset;
110110
}
111111

@@ -114,14 +114,14 @@ private static int WriteInt64(Span<byte> seq, long value)
114114
var offset = 0;
115115
if (value is < 128 and >= -128)
116116
{
117-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Smalllong);
118-
offset += WireFormatting.WriteByte(seq.Slice(offset), (byte)value);
117+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Smalllong);
118+
offset += WireFormatting.WriteByte(seq[offset..], (byte)value);
119119

120120
return offset;
121121
}
122122

123-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Long);
124-
offset += WireFormatting.WriteInt64(seq.Slice(offset), value);
123+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Long);
124+
offset += WireFormatting.WriteInt64(seq[offset..], value);
125125
return offset;
126126
}
127127

@@ -138,60 +138,60 @@ private static int WriteBytes(Span<byte> seq, byte[] value)
138138
// List8
139139
if (len < 256)
140140
{
141-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Vbin8);
142-
offset += WireFormatting.WriteByte(seq.Slice(offset), (byte)len);
143-
offset += WireFormatting.Write(seq.Slice(offset), new ReadOnlySequence<byte>(value));
141+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Vbin8);
142+
offset += WireFormatting.WriteByte(seq[offset..], (byte)len);
143+
offset += WireFormatting.Write(seq[offset..], new ReadOnlySequence<byte>(value));
144144
return offset;
145145
}
146146

147147
// List32
148-
offset += WireFormatting.WriteByte(seq.Slice(offset), FormatCode.Vbin32);
149-
offset += WireFormatting.WriteUInt32(seq.Slice(offset), (uint)len);
150-
offset += WireFormatting.Write(seq.Slice(offset), new ReadOnlySequence<byte>(value));
148+
offset += WireFormatting.WriteByte(seq[offset..], FormatCode.Vbin32);
149+
offset += WireFormatting.WriteUInt32(seq[offset..], (uint)len);
150+
offset += WireFormatting.Write(seq[offset..], new ReadOnlySequence<byte>(value));
151151
return offset;
152152
}
153153

154154
private static int WriteUInt16(Span<byte> seq, ushort value)
155155
{
156156
var offset = WireFormatting.WriteByte(seq, FormatCode.Ushort);
157-
offset += WireFormatting.WriteUInt16(seq.Slice(offset), value);
157+
offset += WireFormatting.WriteUInt16(seq[offset..], value);
158158
return offset;
159159
}
160160

161161
private static int WriteByte(Span<byte> seq, byte value)
162162
{
163163
var offset = WireFormatting.WriteByte(seq, FormatCode.Ubyte);
164-
offset += WireFormatting.WriteByte(seq.Slice(offset), value);
164+
offset += WireFormatting.WriteByte(seq[offset..], value);
165165
return offset;
166166
}
167167

168168
private static int WriteSByte(Span<byte> seq, sbyte value)
169169
{
170170
var offset = WireFormatting.WriteByte(seq, FormatCode.Byte);
171-
offset += WireFormatting.WriteByte(seq.Slice(offset), (byte)value);
171+
offset += WireFormatting.WriteByte(seq[offset..], (byte)value);
172172
return offset;
173173
}
174174

175175
private static int WriteFloat(Span<byte> seq, float value)
176176
{
177177
var offset = WireFormatting.WriteByte(seq, FormatCode.Float);
178178
var intFloat = BitConverter.SingleToInt32Bits(value);
179-
offset += WireFormatting.WriteInt32(seq.Slice(offset), intFloat);
179+
offset += WireFormatting.WriteInt32(seq[offset..], intFloat);
180180
return offset;
181181
}
182182

183183
private static int WriteDouble(Span<byte> seq, double value)
184184
{
185185
var offset = WireFormatting.WriteByte(seq, FormatCode.Double);
186186
var intFloat = BitConverter.DoubleToInt64Bits(value);
187-
offset += WireFormatting.WriteInt64(seq.Slice(offset), intFloat);
187+
offset += WireFormatting.WriteInt64(seq[offset..], intFloat);
188188
return offset;
189189
}
190190

191191
private static int WriteIn16(Span<byte> seq, short value)
192192
{
193193
var offset = WireFormatting.WriteByte(seq, FormatCode.Short);
194-
offset += WireFormatting.WriteInt16(seq.Slice(offset), value);
194+
offset += WireFormatting.WriteInt16(seq[offset..], value);
195195
return offset;
196196
}
197197

@@ -204,7 +204,7 @@ private static int WriteTimestamp(Span<byte> seq, DateTime value)
204204
{
205205
var offset = WireFormatting.WriteByte(seq, FormatCode.Timestamp);
206206
var unixTime = ((DateTimeOffset)value).ToUnixTimeMilliseconds();
207-
offset += WireFormatting.WriteUInt64(seq.Slice(offset), (ulong)unixTime);
207+
offset += WireFormatting.WriteUInt64(seq[offset..], (ulong)unixTime);
208208
return offset;
209209
}
210210

RabbitMQ.Stream.Client/AMQP/Data.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,16 @@ public int Write(Span<byte> span)
3232
var offset = DescribedFormatCode.Write(span, DescribedFormatCode.ApplicationData);
3333
if (data.Length <= byte.MaxValue)
3434
{
35-
offset += WireFormatting.WriteByte(span.Slice(offset), FormatCode.Vbin8); //binary marker
36-
offset += WireFormatting.WriteByte(span.Slice(offset), (byte)data.Length); //length
35+
offset += WireFormatting.WriteByte(span[offset..], FormatCode.Vbin8); //binary marker
36+
offset += WireFormatting.WriteByte(span[offset..], (byte)data.Length); //length
3737
}
3838
else
3939
{
40-
offset += WireFormatting.WriteByte(span.Slice(offset), FormatCode.Vbin32); //binary marker
41-
offset += WireFormatting.WriteUInt32(span.Slice(offset), (uint)data.Length); //length
40+
offset += WireFormatting.WriteByte(span[offset..], FormatCode.Vbin32); //binary marker
41+
offset += WireFormatting.WriteUInt32(span[offset..], (uint)data.Length); //length
4242
}
4343

44-
offset += WireFormatting.Write(span.Slice(offset), data);
44+
offset += WireFormatting.Write(span[offset..], data);
4545
return offset;
4646
}
4747

RabbitMQ.Stream.Client/AMQP/DescribedFormatCode.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ public static class DescribedFormatCode
1515
[MethodImpl(MethodImplOptions.AggressiveInlining)]
1616
public static byte Read(ref SequenceReader<byte> reader)
1717
{
18+
// DescribedFormatCode in this case we need to read
19+
// only the last byte form the header to get the format code
20+
// the first can be ignored but it is necessary to read them
1821
reader.TryRead(out _);
1922
reader.TryRead(out _);
2023
reader.TryRead(out var formatCode);

RabbitMQ.Stream.Client/AMQP/Map.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -72,15 +72,15 @@ public int Size
7272
public int Write(Span<byte> span)
7373
{
7474
var offset = DescribedFormatCode.Write(span, MapDataCode);
75-
offset += WireFormatting.WriteByte(span.Slice(offset), FormatCode.Map32);
76-
offset += WireFormatting.WriteUInt32(span.Slice(offset), (uint)MapSize()); // MapSize
77-
offset += WireFormatting.WriteUInt32(span.Slice(offset), (uint)Count * 2); // pair values
75+
offset += WireFormatting.WriteByte(span[offset..], FormatCode.Map32);
76+
offset += WireFormatting.WriteUInt32(span[offset..], (uint)MapSize()); // MapSize
77+
offset += WireFormatting.WriteUInt32(span[offset..], (uint)Count * 2); // pair values
7878
foreach (var (key, value) in this)
7979
{
8080
if (!IsNullOrEmptyString(key))
8181
{
82-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), key);
83-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), value);
82+
offset += AmqpWireFormatting.WriteAny(span[offset..], key);
83+
offset += AmqpWireFormatting.WriteAny(span[offset..], value);
8484
}
8585
}
8686

RabbitMQ.Stream.Client/AMQP/Properties.cs

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -132,22 +132,22 @@ public int Size
132132
public int Write(Span<byte> span)
133133
{
134134
var offset = DescribedFormatCode.Write(span, DescribedFormatCode.MessageProperties);
135-
offset += WireFormatting.WriteByte(span.Slice(offset), FormatCode.List32);
136-
offset += WireFormatting.WriteUInt32(span.Slice(offset), (uint)PropertySize()); // PropertySize
137-
offset += WireFormatting.WriteUInt32(span.Slice(offset), 13); // field numbers
138-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), MessageId);
139-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), UserId);
140-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), To);
141-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), Subject);
142-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), ReplyTo);
143-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), CorrelationId);
144-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), ContentType);
145-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), ContentEncoding);
146-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), AbsoluteExpiryTime);
147-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), CreationTime);
148-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), GroupId);
149-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), GroupSequence);
150-
offset += AmqpWireFormatting.WriteAny(span.Slice(offset), ReplyToGroupId);
135+
offset += WireFormatting.WriteByte(span[offset..], FormatCode.List32);
136+
offset += WireFormatting.WriteUInt32(span[offset..], (uint)PropertySize()); // PropertySize
137+
offset += WireFormatting.WriteUInt32(span[offset..], 13); // field numbers
138+
offset += AmqpWireFormatting.WriteAny(span[offset..], MessageId);
139+
offset += AmqpWireFormatting.WriteAny(span[offset..], UserId);
140+
offset += AmqpWireFormatting.WriteAny(span[offset..], To);
141+
offset += AmqpWireFormatting.WriteAny(span[offset..], Subject);
142+
offset += AmqpWireFormatting.WriteAny(span[offset..], ReplyTo);
143+
offset += AmqpWireFormatting.WriteAny(span[offset..], CorrelationId);
144+
offset += AmqpWireFormatting.WriteAny(span[offset..], ContentType);
145+
offset += AmqpWireFormatting.WriteAny(span[offset..], ContentEncoding);
146+
offset += AmqpWireFormatting.WriteAny(span[offset..], AbsoluteExpiryTime);
147+
offset += AmqpWireFormatting.WriteAny(span[offset..], CreationTime);
148+
offset += AmqpWireFormatting.WriteAny(span[offset..], GroupId);
149+
offset += AmqpWireFormatting.WriteAny(span[offset..], GroupSequence);
150+
offset += AmqpWireFormatting.WriteAny(span[offset..], ReplyToGroupId);
151151
return offset;
152152
}
153153
}

RabbitMQ.Stream.Client/Message.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,20 +46,20 @@ public int Write(Span<byte> span)
4646
var offset = 0;
4747
if (Properties != null)
4848
{
49-
offset += Properties.Write(span.Slice(offset));
49+
offset += Properties.Write(span[offset..]);
5050
}
5151

5252
if (ApplicationProperties != null)
5353
{
54-
offset += ApplicationProperties.Write(span.Slice(offset));
54+
offset += ApplicationProperties.Write(span[offset..]);
5555
}
5656

5757
if (Annotations != null)
5858
{
59-
offset += Annotations.Write(span.Slice(offset));
59+
offset += Annotations.Write(span[offset..]);
6060
}
6161

62-
offset += Data.Write(span.Slice(offset));
62+
offset += Data.Write(span[offset..]);
6363
return offset;
6464
}
6565

RabbitMQ.Stream.Client/MetaData.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ public int Write(Span<byte> span)
3939
{
4040
var command = (ICommand)this;
4141
var offset = WireFormatting.WriteUInt16(span, Key);
42-
offset += WireFormatting.WriteUInt16(span.Slice(offset), command.Version);
43-
offset += WireFormatting.WriteUInt32(span.Slice(offset), correlationId);
42+
offset += WireFormatting.WriteUInt16(span[offset..], command.Version);
43+
offset += WireFormatting.WriteUInt32(span[offset..], correlationId);
4444
// map
45-
offset += WireFormatting.WriteInt32(span.Slice(offset), streams.Count());
45+
offset += WireFormatting.WriteInt32(span[offset..], streams.Count());
4646
foreach (var s in streams)
4747
{
48-
offset += WireFormatting.WriteString(span.Slice(offset), s);
48+
offset += WireFormatting.WriteString(span[offset..], s);
4949
}
5050

5151
return offset;

RabbitMQ.Stream.Client/Publish.cs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,17 +40,17 @@ public Publish(byte publisherId, List<(ulong, Message)> messages)
4040
public int Write(Span<byte> span)
4141
{
4242
var offset = WireFormatting.WriteUInt16(span, Key);
43-
offset += WireFormatting.WriteUInt16(span.Slice(offset), Version);
44-
offset += WireFormatting.WriteByte(span.Slice(offset), publisherId);
43+
offset += WireFormatting.WriteUInt16(span[offset..], Version);
44+
offset += WireFormatting.WriteByte(span[offset..], publisherId);
4545
// this assumes we never write an empty publish frame
46-
offset += WireFormatting.WriteInt32(span.Slice(offset), MessageCount);
46+
offset += WireFormatting.WriteInt32(span[offset..], MessageCount);
4747
foreach (var (publishingId, msg) in messages)
4848
{
49-
offset += WireFormatting.WriteUInt64(span.Slice(offset), publishingId);
49+
offset += WireFormatting.WriteUInt64(span[offset..], publishingId);
5050
// this only write "simple" messages, we assume msg is just the binary body
5151
// not stream encoded data
52-
offset += WireFormatting.WriteUInt32(span.Slice(offset), (uint)msg.Size);
53-
offset += msg.Write(span.Slice(offset));
52+
offset += WireFormatting.WriteUInt32(span[offset..], (uint)msg.Size);
53+
offset += msg.Write(span[offset..]);
5454
}
5555

5656
return offset;

0 commit comments

Comments
 (0)