Skip to content

Commit 592cea6

Browse files
authored
Optimize writing single segment sequences (#24929)
1 parent 28dc9bf commit 592cea6

File tree

4 files changed

+24
-24
lines changed

4 files changed

+24
-24
lines changed

src/Servers/Kestrel/Core/src/Internal/Http/Http1ChunkedEncodingMessageBody.cs

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -218,21 +218,6 @@ private async Task StopAsyncAwaited()
218218
_requestBodyPipe.Reset();
219219
}
220220

221-
private void Copy(in ReadOnlySequence<byte> readableBuffer, PipeWriter writableBuffer)
222-
{
223-
if (readableBuffer.IsSingleSegment)
224-
{
225-
writableBuffer.Write(readableBuffer.FirstSpan);
226-
}
227-
else
228-
{
229-
foreach (var memory in readableBuffer)
230-
{
231-
writableBuffer.Write(memory.Span);
232-
}
233-
}
234-
}
235-
236221
protected override void OnReadStarted()
237222
{
238223
_pumpTask = PumpAsync();
@@ -442,7 +427,7 @@ private void ReadChunkedData(in ReadOnlySequence<byte> buffer, PipeWriter writab
442427
consumed = buffer.GetPosition(actual);
443428
examined = consumed;
444429

445-
Copy(buffer.Slice(0, actual), writableBuffer);
430+
buffer.Slice(0, actual).CopyTo(writableBuffer);
446431

447432
_inputLength -= actual;
448433
AddAndCheckObservedBytes(actual);

src/Servers/Kestrel/Core/src/Internal/Http2/Http2FrameWriter.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,7 @@ private void WriteDataUnsynchronized(int streamId, in ReadOnlySequence<byte> dat
357357

358358
WriteHeaderUnsynchronized();
359359

360-
foreach (var buffer in data)
361-
{
362-
_outputWriter.Write(buffer.Span);
363-
}
360+
data.CopyTo(_outputWriter);
364361

365362
// Plus padding
366363
return;

src/Servers/Kestrel/Core/src/Internal/Http2/Http2Stream.cs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -440,10 +440,7 @@ public Task OnDataAsync(Http2Frame dataFrame, in ReadOnlySequence<byte> payload)
440440
// Ignore data frames for aborted streams, but only after counting them for purposes of connection level flow control.
441441
if (!IsAborted)
442442
{
443-
foreach (var segment in dataPayload)
444-
{
445-
RequestBodyPipe.Writer.Write(segment.Span);
446-
}
443+
dataPayload.CopyTo(RequestBodyPipe.Writer);
447444

448445
// If the stream is completed go ahead and call RequestBodyPipe.Writer.Complete().
449446
// Data will still be available to the reader.

src/Shared/ServerInfrastructure/BufferExtensions.cs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,27 @@ public static ReadOnlySpan<byte> ToSpan(in this ReadOnlySequence<byte> buffer)
2626
return buffer.ToArray();
2727
}
2828

29+
[MethodImpl(MethodImplOptions.AggressiveInlining)]
30+
public static void CopyTo(in this ReadOnlySequence<byte> buffer, PipeWriter pipeWriter)
31+
{
32+
if (buffer.IsSingleSegment)
33+
{
34+
pipeWriter.Write(buffer.FirstSpan);
35+
}
36+
else
37+
{
38+
CopyToMultiSegment(buffer, pipeWriter);
39+
}
40+
}
41+
42+
private static void CopyToMultiSegment(in ReadOnlySequence<byte> buffer, PipeWriter pipeWriter)
43+
{
44+
foreach (var item in buffer)
45+
{
46+
pipeWriter.Write(item.Span);
47+
}
48+
}
49+
2950
public static ArraySegment<byte> GetArray(this Memory<byte> buffer)
3051
{
3152
return ((ReadOnlyMemory<byte>)buffer).GetArray();

0 commit comments

Comments
 (0)