Skip to content

Commit 095ace1

Browse files
authored
Merge pull request #342 from bgrainger/reduce-allocations
Reduce allocations.
2 parents 2194d88 + 978129e commit 095ace1

File tree

5 files changed

+25
-34
lines changed

5 files changed

+25
-34
lines changed

src/MySqlConnector/MySqlClient/Results/ResultSet.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,17 @@ private ValueTask<Row> ScanRowAsync(IOBehavior ioBehavior, Row row, Cancellation
167167
{
168168
// if we've already read past the end of this resultset, Read returns false
169169
if (BufferState == ResultSetState.HasMoreData || BufferState == ResultSetState.NoMoreData || BufferState == ResultSetState.None)
170-
return new ValueTask<Row>((Row)null);
170+
return new ValueTask<Row>((Row) null);
171171

172172
using (Command.RegisterCancel(cancellationToken))
173173
{
174174
var payloadValueTask = Session.ReceiveReplyAsync(ioBehavior, CancellationToken.None);
175175
return payloadValueTask.IsCompletedSuccessfully
176-
? new ValueTask<Row>(ScanRowAsyncRemainder(payloadValueTask.Result))
177-
: new ValueTask<Row>(ScanRowAsyncAwaited(payloadValueTask.AsTask(), cancellationToken));
176+
? new ValueTask<Row>(ScanRowAsyncRemainder(payloadValueTask.Result, row))
177+
: new ValueTask<Row>(ScanRowAsyncAwaited(payloadValueTask.AsTask(), row, cancellationToken));
178178
}
179179

180-
async Task<Row> ScanRowAsyncAwaited(Task<PayloadData> payloadTask, CancellationToken token)
180+
async Task<Row> ScanRowAsyncAwaited(Task<PayloadData> payloadTask, Row row_, CancellationToken token)
181181
{
182182
PayloadData payloadData;
183183
try
@@ -191,10 +191,10 @@ async Task<Row> ScanRowAsyncAwaited(Task<PayloadData> payloadTask, CancellationT
191191
token.ThrowIfCancellationRequested();
192192
throw;
193193
}
194-
return ScanRowAsyncRemainder(payloadData);
194+
return ScanRowAsyncRemainder(payloadData, row_);
195195
}
196196

197-
Row ScanRowAsyncRemainder(PayloadData payload)
197+
Row ScanRowAsyncRemainder(PayloadData payload, Row row_)
198198
{
199199
if (payload.HeaderByte == EofPayload.Signature)
200200
{
@@ -223,12 +223,12 @@ Row ScanRowAsyncRemainder(PayloadData payload)
223223
reader.Offset += m_dataLengths[column];
224224
}
225225

226-
if (row == null)
227-
row = new Row(this);
228-
row.SetData(m_dataLengths, m_dataOffsets, payload.ArraySegment);
229-
m_rowBuffered = row;
226+
if (row_ == null)
227+
row_ = new Row(this);
228+
row_.SetData(m_dataLengths, m_dataOffsets, payload.ArraySegment);
229+
m_rowBuffered = row_;
230230
m_hasRows = true;
231-
return row;
231+
return row_;
232232
}
233233
}
234234

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
1-
using System;
1+
using System;
22

33
namespace MySql.Data.Protocol.Serialization
44
{
5-
internal class Packet
5+
internal struct Packet
66
{
7-
public Packet(int sequenceNumber, ArraySegment<byte> contents)
7+
public Packet(ArraySegment<byte> contents)
88
{
9-
SequenceNumber = sequenceNumber;
109
Contents = contents;
1110
}
1211

13-
public int SequenceNumber { get; }
1412
public ArraySegment<byte> Contents { get; }
1513
}
1614
}

src/MySqlConnector/Protocol/Serialization/ProtocolUtility.cs

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Buffers;
33
using System.IO;
44
using System.Threading.Tasks;
@@ -45,16 +45,16 @@ private static ValueTask<Packet> ReadPacketAfterHeader(ArraySegment<byte> header
4545

4646
var payloadBytesTask = bufferedByteReader.ReadBytesAsync(byteHandler, payloadLength, ioBehavior);
4747
if (payloadBytesTask.IsCompleted)
48-
return CreatePacketFromPayload(payloadBytesTask.Result, payloadLength, packetSequenceNumber, protocolErrorBehavior);
49-
return AddContinuation(payloadBytesTask, payloadLength, packetSequenceNumber, protocolErrorBehavior);
48+
return CreatePacketFromPayload(payloadBytesTask.Result, payloadLength, protocolErrorBehavior);
49+
return AddContinuation(payloadBytesTask, payloadLength, protocolErrorBehavior);
5050

5151
// NOTE: use a local function (with no captures) to defer creation of lambda objects
52-
ValueTask<Packet> AddContinuation(ValueTask<ArraySegment<byte>> payloadBytesTask_, int payloadLength_, int packetSequenceNumber_, ProtocolErrorBehavior protocolErrorBehavior_)
53-
=> payloadBytesTask_.ContinueWith(x => CreatePacketFromPayload(x, payloadLength_, packetSequenceNumber_, protocolErrorBehavior_));
52+
ValueTask<Packet> AddContinuation(ValueTask<ArraySegment<byte>> payloadBytesTask_, int payloadLength_, ProtocolErrorBehavior protocolErrorBehavior_)
53+
=> payloadBytesTask_.ContinueWith(x => CreatePacketFromPayload(x, payloadLength_, protocolErrorBehavior_));
5454
}
5555

56-
private static ValueTask<Packet> CreatePacketFromPayload(ArraySegment<byte> payloadBytes, int payloadLength, int packetSequenceNumber, ProtocolErrorBehavior protocolErrorBehavior) =>
57-
payloadBytes.Count >= payloadLength ? new ValueTask<Packet>(new Packet(packetSequenceNumber, payloadBytes)) :
56+
private static ValueTask<Packet> CreatePacketFromPayload(ArraySegment<byte> payloadBytes, int payloadLength, ProtocolErrorBehavior protocolErrorBehavior) =>
57+
payloadBytes.Count >= payloadLength ? new ValueTask<Packet>(new Packet(payloadBytes)) :
5858
protocolErrorBehavior == ProtocolErrorBehavior.Throw ? ValueTaskExtensions.FromException<Packet>(new EndOfStreamException()) :
5959
default(ValueTask<Packet>);
6060

@@ -69,8 +69,7 @@ private static ValueTask<ArraySegment<byte>> DoReadPayloadAsync(BufferedByteRead
6969
var readPacketTask = ReadPacketAsync(bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior);
7070
while (readPacketTask.IsCompleted)
7171
{
72-
ValueTask<ArraySegment<byte>> result;
73-
if (HasReadPayload(previousPayloads, readPacketTask.Result, protocolErrorBehavior, out result))
72+
if (HasReadPayload(previousPayloads, readPacketTask.Result, protocolErrorBehavior, out var result))
7473
return result;
7574

7675
readPacketTask = ReadPacketAsync(bufferedByteReader, byteHandler, getNextSequenceNumber, protocolErrorBehavior, ioBehavior);
@@ -89,12 +88,6 @@ ValueTask<ArraySegment<byte>> AddContinuation(ValueTask<Packet> readPacketTask_,
8988

9089
private static bool HasReadPayload(ArraySegmentHolder<byte> previousPayloads, Packet packet, ProtocolErrorBehavior protocolErrorBehavior, out ValueTask<ArraySegment<byte>> result)
9190
{
92-
if (packet == null && protocolErrorBehavior == ProtocolErrorBehavior.Ignore)
93-
{
94-
result = default(ValueTask<ArraySegment<byte>>);
95-
return true;
96-
}
97-
9891
if (previousPayloads.Count == 0 && packet.Contents.Count < MaxPacketSize)
9992
{
10093
result = new ValueTask<ArraySegment<byte>>(packet.Contents);

tests/Benchmark/Benchmark.csproj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22
<PropertyGroup>
33
<OutputType>Exe</OutputType>
4-
<TargetFrameworks>netcoreapp1.1;net462;netcoreapp2.0</TargetFrameworks>
4+
<TargetFrameworks>netcoreapp1.1;net47;netcoreapp2.0</TargetFrameworks>
55
</PropertyGroup>
66
<ItemGroup>
77
<PackageReference Include="BenchmarkDotNet" Version="0.10.8" />

tests/Benchmark/Program.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using System;
1+
using System;
22
using System.Data.Common;
33
using System.Threading.Tasks;
44
using BenchmarkDotNet.Attributes;
@@ -24,7 +24,7 @@ static void Main()
2424
.With(JitOptimizationsValidator.FailOnError)
2525
.With(MemoryDiagnoser.Default)
2626
.With(StatisticColumn.AllStatistics)
27-
.With(Job.Default.With(Runtime.Clr).With(Jit.RyuJit).With(Platform.X64).With(CsProjClassicNetToolchain.Net462).WithId("net462"))
27+
.With(Job.Default.With(Runtime.Clr).With(Jit.RyuJit).With(Platform.X64).With(CsProjClassicNetToolchain.Net47).WithId("net47"))
2828
.With(Job.Default.With(Runtime.Core).With(CsProjCoreToolchain.NetCoreApp11).WithId("netcore11"))
2929
.With(Job.Default.With(Runtime.Core).With(CsProjCoreToolchain.NetCoreApp20).WithId("netcore20"))
3030
.With(DefaultExporters.Csv);

0 commit comments

Comments
 (0)