Optimize writing single segment sequences (#24929)
This commit is contained in:
parent
28dc9bffab
commit
592cea6a2b
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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();
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue