Added fast path for single memory ReadableBuffer (#1512)
* Special case single buffer * Added fast path for single span buffers in UvWriteReq
This commit is contained in:
parent
2ed456fd68
commit
39819d6708
|
|
@ -109,11 +109,19 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Adapter.Internal
|
||||||
await _outputStream.FlushAsync();
|
await _outputStream.FlushAsync();
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var memory in buffer)
|
if (buffer.IsSingleSpan)
|
||||||
{
|
{
|
||||||
var array = memory.GetArray();
|
var array = buffer.First.GetArray();
|
||||||
await _outputStream.WriteAsync(array.Array, array.Offset, array.Count);
|
await _outputStream.WriteAsync(array.Array, array.Offset, array.Count);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var memory in buffer)
|
||||||
|
{
|
||||||
|
var array = memory.GetArray();
|
||||||
|
await _outputStream.WriteAsync(array.Array, array.Offset, array.Count);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.Buffers;
|
using System.Buffers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO.Pipelines;
|
using System.IO.Pipelines;
|
||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
|
||||||
|
|
@ -68,9 +67,16 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Networking
|
||||||
_pins.Add(GCHandle.Alloc(this, GCHandleType.Normal));
|
_pins.Add(GCHandle.Alloc(this, GCHandleType.Normal));
|
||||||
|
|
||||||
var nBuffers = 0;
|
var nBuffers = 0;
|
||||||
foreach (var _ in buffer)
|
if (buffer.IsSingleSpan)
|
||||||
{
|
{
|
||||||
nBuffers++;
|
nBuffers = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foreach (var _ in buffer)
|
||||||
|
{
|
||||||
|
nBuffers++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var pBuffers = (Libuv.uv_buf_t*)_bufs;
|
var pBuffers = (Libuv.uv_buf_t*)_bufs;
|
||||||
|
|
@ -82,19 +88,33 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Internal.Networking
|
||||||
_pins.Add(gcHandle);
|
_pins.Add(gcHandle);
|
||||||
pBuffers = (Libuv.uv_buf_t*)gcHandle.AddrOfPinnedObject();
|
pBuffers = (Libuv.uv_buf_t*)gcHandle.AddrOfPinnedObject();
|
||||||
}
|
}
|
||||||
var index = 0;
|
|
||||||
foreach (var memory in buffer)
|
if (nBuffers == 1)
|
||||||
{
|
{
|
||||||
// REVIEW: This isn't necessary for our default pool since the memory is
|
var memory = buffer.First;
|
||||||
// already pinned but it also makes tests pass
|
|
||||||
var memoryHandle = memory.Pin();
|
var memoryHandle = memory.Pin();
|
||||||
_handles.Add(memoryHandle);
|
_handles.Add(memoryHandle);
|
||||||
|
|
||||||
// create and pin each segment being written
|
// Fast path for single buffer
|
||||||
pBuffers[index] = Libuv.buf_init(
|
pBuffers[0] = Libuv.buf_init(
|
||||||
(IntPtr)memoryHandle.PinnedPointer,
|
(IntPtr)memoryHandle.PinnedPointer,
|
||||||
memory.Length);
|
memory.Length);
|
||||||
index++;
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var index = 0;
|
||||||
|
foreach (var memory in buffer)
|
||||||
|
{
|
||||||
|
// This won't actually pin the buffer since we're already using pinned memory
|
||||||
|
var memoryHandle = memory.Pin();
|
||||||
|
_handles.Add(memoryHandle);
|
||||||
|
|
||||||
|
// create and pin each segment being written
|
||||||
|
pBuffers[index] = Libuv.buf_init(
|
||||||
|
(IntPtr)memoryHandle.PinnedPointer,
|
||||||
|
memory.Length);
|
||||||
|
index++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_callback = callback;
|
_callback = callback;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue