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();
}
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()
{
_pumpTask = PumpAsync();
@ -442,7 +427,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
consumed = buffer.GetPosition(actual);
examined = consumed;
Copy(buffer.Slice(0, actual), writableBuffer);
buffer.Slice(0, actual).CopyTo(writableBuffer);
_inputLength -= actual;
AddAndCheckObservedBytes(actual);

View File

@ -357,10 +357,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2
WriteHeaderUnsynchronized();
foreach (var buffer in data)
{
_outputWriter.Write(buffer.Span);
}
data.CopyTo(_outputWriter);
// Plus padding
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.
if (!IsAborted)
{
foreach (var segment in dataPayload)
{
RequestBodyPipe.Writer.Write(segment.Span);
}
dataPayload.CopyTo(RequestBodyPipe.Writer);
// If the stream is completed go ahead and call RequestBodyPipe.Writer.Complete().
// Data will still be available to the reader.

View File

@ -26,6 +26,27 @@ namespace System.Buffers
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)
{
return ((ReadOnlyMemory<byte>)buffer).GetArray();