Optimize writing single segment sequences (#24929)

This commit is contained in:
James Newton-King 2020-08-18 19:37:48 +12:00 committed by GitHub
parent 28dc9bffab
commit 592cea6a2b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 24 additions and 24 deletions

View File

@ -218,21 +218,6 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
_requestBodyPipe.Reset(); _requestBodyPipe.Reset();
} }
private void Copy(in ReadOnlySequence<byte> readableBuffer, PipeWriter writableBuffer)
{
if (readableBuffer.IsSingleSegment)
{
writableBuffer.Write(readableBuffer.FirstSpan);
}
else
{
foreach (var memory in readableBuffer)
{
writableBuffer.Write(memory.Span);
}
}
}
protected override void OnReadStarted() protected override void OnReadStarted()
{ {
_pumpTask = PumpAsync(); _pumpTask = PumpAsync();
@ -442,7 +427,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
consumed = buffer.GetPosition(actual); consumed = buffer.GetPosition(actual);
examined = consumed; examined = consumed;
Copy(buffer.Slice(0, actual), writableBuffer); buffer.Slice(0, actual).CopyTo(writableBuffer);
_inputLength -= actual; _inputLength -= actual;
AddAndCheckObservedBytes(actual); AddAndCheckObservedBytes(actual);

View File

@ -357,10 +357,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
WriteHeaderUnsynchronized(); WriteHeaderUnsynchronized();
foreach (var buffer in data) data.CopyTo(_outputWriter);
{
_outputWriter.Write(buffer.Span);
}
// Plus padding // Plus padding
return; return;

View File

@ -440,10 +440,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
// Ignore data frames for aborted streams, but only after counting them for purposes of connection level flow control. // Ignore data frames for aborted streams, but only after counting them for purposes of connection level flow control.
if (!IsAborted) if (!IsAborted)
{ {
foreach (var segment in dataPayload) dataPayload.CopyTo(RequestBodyPipe.Writer);
{
RequestBodyPipe.Writer.Write(segment.Span);
}
// If the stream is completed go ahead and call RequestBodyPipe.Writer.Complete(). // If the stream is completed go ahead and call RequestBodyPipe.Writer.Complete().
// Data will still be available to the reader. // Data will still be available to the reader.

View File

@ -26,6 +26,27 @@ namespace System.Buffers
return buffer.ToArray(); return buffer.ToArray();
} }
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static void CopyTo(in this ReadOnlySequence<byte> buffer, PipeWriter pipeWriter)
{
if (buffer.IsSingleSegment)
{
pipeWriter.Write(buffer.FirstSpan);
}
else
{
CopyToMultiSegment(buffer, pipeWriter);
}
}
private static void CopyToMultiSegment(in ReadOnlySequence<byte> buffer, PipeWriter pipeWriter)
{
foreach (var item in buffer)
{
pipeWriter.Write(item.Span);
}
}
public static ArraySegment<byte> GetArray(this Memory<byte> buffer) public static ArraySegment<byte> GetArray(this Memory<byte> buffer)
{ {
return ((ReadOnlyMemory<byte>)buffer).GetArray(); return ((ReadOnlyMemory<byte>)buffer).GetArray();