Skip to content

Commit 1f76567

Browse files
committed
Reduce temporary allocations for GetNextSequenceNumber.
Also switch to using -1 as a sentinel instead of null to reuse function signature between read and write. This reduces allocations for the "ManyRowsNewSync" scenario by 49%.
1 parent 25bb590 commit 1f76567

File tree

3 files changed

+12
-12
lines changed

3 files changed

+12
-12
lines changed

src/MySqlConnector/Protocol/Serialization/CompressedPayloadHandler.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public IByteHandler ByteHandler
3131
}
3232

3333
public ValueTask<ArraySegment<byte>> ReadPayloadAsync(ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior) =>
34-
ProtocolUtility.ReadPayloadAsync(m_bufferedByteReader, new CompressedByteHandler(this, protocolErrorBehavior), () => default(int?), default(ArraySegment<byte>), protocolErrorBehavior, ioBehavior);
34+
ProtocolUtility.ReadPayloadAsync(m_bufferedByteReader, new CompressedByteHandler(this, protocolErrorBehavior), () => -1, default(ArraySegment<byte>), protocolErrorBehavior, ioBehavior);
3535

3636
public ValueTask<int> WritePayloadAsync(ArraySegment<byte> payload, IOBehavior ioBehavior)
3737
{

src/MySqlConnector/Protocol/Serialization/ProtocolUtility.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,19 @@ namespace MySql.Data.Protocol.Serialization
99
{
1010
internal static class ProtocolUtility
1111
{
12-
public static ValueTask<Packet> ReadPacketAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func<int?> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
12+
public static ValueTask<Packet> ReadPacketAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func<int> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
1313
{
1414
var headerBytesTask = bufferedByteReader.ReadBytesAsync(byteHandler, 4, ioBehavior);
1515
if (headerBytesTask.IsCompleted)
1616
return ReadPacketAfterHeader(headerBytesTask.Result, bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior);
1717
return AddContinuation(headerBytesTask, bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior);
1818

1919
// NOTE: use a local function (with no captures) to defer creation of lambda objects
20-
ValueTask<Packet> AddContinuation(ValueTask<ArraySegment<byte>> headerBytes_, BufferedByteReader bufferedByteReader_, IByteHandler byteHandler_, Func<int?> getNextSequenceNumber_, ProtocolErrorBehavior protocolErrorBehavior_, IOBehavior ioBehavior_) =>
20+
ValueTask<Packet> AddContinuation(ValueTask<ArraySegment<byte>> headerBytes_, BufferedByteReader bufferedByteReader_, IByteHandler byteHandler_, Func<int> getNextSequenceNumber_, ProtocolErrorBehavior protocolErrorBehavior_, IOBehavior ioBehavior_) =>
2121
headerBytes_.ContinueWith(x => ReadPacketAfterHeader(x, bufferedByteReader_, byteHandler_, getNextSequenceNumber_, protocolErrorBehavior_, ioBehavior_));
2222
}
2323

24-
private static ValueTask<Packet> ReadPacketAfterHeader(ArraySegment<byte> headerBytes, BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func<int?> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
24+
private static ValueTask<Packet> ReadPacketAfterHeader(ArraySegment<byte> headerBytes, BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func<int> getNextSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
2525
{
2626
if (headerBytes.Count < 4)
2727
{
@@ -34,12 +34,12 @@ private static ValueTask<Packet> ReadPacketAfterHeader(ArraySegment<byte> header
3434
int packetSequenceNumber = headerBytes.Array[headerBytes.Offset + 3];
3535

3636
var expectedSequenceNumber = getNextSequenceNumber() % 256;
37-
if (expectedSequenceNumber.HasValue && packetSequenceNumber != expectedSequenceNumber.Value)
37+
if (expectedSequenceNumber != -1 && packetSequenceNumber != expectedSequenceNumber)
3838
{
3939
if (protocolErrorBehavior == ProtocolErrorBehavior.Ignore)
4040
return default(ValueTask<Packet>);
4141

42-
var exception = MySqlProtocolException.CreateForPacketOutOfOrder(expectedSequenceNumber.Value, packetSequenceNumber);
42+
var exception = MySqlProtocolException.CreateForPacketOutOfOrder(expectedSequenceNumber, packetSequenceNumber);
4343
return ValueTaskExtensions.FromException<Packet>(exception);
4444
}
4545

@@ -58,7 +58,7 @@ private static ValueTask<Packet> CreatePacketFromPayload(ArraySegment<byte> payl
5858
protocolErrorBehavior == ProtocolErrorBehavior.Throw ? ValueTaskExtensions.FromException<Packet>(new EndOfStreamException()) :
5959
default(ValueTask<Packet>);
6060

61-
public static ValueTask<ArraySegment<byte>> ReadPayloadAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func<int?> getNextSequenceNumber, ArraySegment<byte> previousPayloads, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
61+
public static ValueTask<ArraySegment<byte>> ReadPayloadAsync(BufferedByteReader bufferedByteReader, IByteHandler byteHandler, Func<int> getNextSequenceNumber, ArraySegment<byte> previousPayloads, ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior)
6262
{
6363
var readPacketTask = ReadPacketAsync(bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior);
6464
while (readPacketTask.IsCompleted)
@@ -73,7 +73,7 @@ public static ValueTask<ArraySegment<byte>> ReadPayloadAsync(BufferedByteReader
7373
return AddContinuation(readPacketTask, bufferedByteReader, byteHandler, getNextSequenceNumber, previousPayloads, protocolErrorBehavior, ioBehavior);
7474

7575
// NOTE: use a local function (with no captures) to defer creation of lambda objects
76-
ValueTask<ArraySegment<byte>> AddContinuation(ValueTask<Packet> readPacketTask_, BufferedByteReader bufferedByteReader_, IByteHandler byteHandler_, Func<int?> getNextSequenceNumber_, ArraySegment<byte> previousPayloads_, ProtocolErrorBehavior protocolErrorBehavior_, IOBehavior ioBehavior_)
76+
ValueTask<ArraySegment<byte>> AddContinuation(ValueTask<Packet> readPacketTask_, BufferedByteReader bufferedByteReader_, IByteHandler byteHandler_, Func<int> getNextSequenceNumber_, ArraySegment<byte> previousPayloads_, ProtocolErrorBehavior protocolErrorBehavior_, IOBehavior ioBehavior_)
7777
{
7878
return readPacketTask_.ContinueWith(packet =>
7979
HasReadPayload(ref previousPayloads_, packet, protocolErrorBehavior_, out var result_) ? result_ :

src/MySqlConnector/Protocol/Serialization/StandardPayloadHandler.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ internal sealed class StandardPayloadHandler : IPayloadHandler
88
public StandardPayloadHandler(IByteHandler byteHandler)
99
{
1010
ByteHandler = byteHandler;
11+
m_getNextSequenceNumber = () => m_sequenceNumber++;
1112
}
1213

1314
public void StartNewConversation()
@@ -26,13 +27,12 @@ public IByteHandler ByteHandler
2627
}
2728

2829
public ValueTask<ArraySegment<byte>> ReadPayloadAsync(ProtocolErrorBehavior protocolErrorBehavior, IOBehavior ioBehavior) =>
29-
ProtocolUtility.ReadPayloadAsync(m_bufferedByteReader, m_byteHandler, () => GetNextSequenceNumber(), default(ArraySegment<byte>), protocolErrorBehavior, ioBehavior);
30+
ProtocolUtility.ReadPayloadAsync(m_bufferedByteReader, m_byteHandler, m_getNextSequenceNumber, default(ArraySegment<byte>), protocolErrorBehavior, ioBehavior);
3031

3132
public ValueTask<int> WritePayloadAsync(ArraySegment<byte> payload, IOBehavior ioBehavior) =>
32-
ProtocolUtility.WritePayloadAsync(m_byteHandler, GetNextSequenceNumber, payload, ioBehavior);
33-
34-
private int GetNextSequenceNumber() => m_sequenceNumber++;
33+
ProtocolUtility.WritePayloadAsync(m_byteHandler, m_getNextSequenceNumber, payload, ioBehavior);
3534

35+
readonly Func<int> m_getNextSequenceNumber;
3636
IByteHandler m_byteHandler;
3737
BufferedByteReader m_bufferedByteReader;
3838
int m_sequenceNumber;

0 commit comments

Comments
 (0)