Skip to content

Commit

Permalink
Added fast path for single memory ReadableBuffer (aspnet#1512)
Browse files Browse the repository at this point in the history
* Special case single buffer
* Added fast path for single span buffers in UvWriteReq
  • Loading branch information
davidfowl authored Mar 20, 2017
1 parent 2ed456f commit 39819d6
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,11 +109,19 @@ public async Task WriteOutputAsync()
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);
}
else
{
foreach (var memory in buffer)
{
var array = memory.GetArray();
await _outputStream.WriteAsync(array.Array, array.Offset, array.Count);
}
}
}
finally
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
using System;
using System.Buffers;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO.Pipelines;
using System.Runtime.InteropServices;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
Expand Down Expand Up @@ -68,9 +67,16 @@ private unsafe void Write(
_pins.Add(GCHandle.Alloc(this, GCHandleType.Normal));

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;
Expand All @@ -82,19 +88,33 @@ private unsafe void Write(
_pins.Add(gcHandle);
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
// already pinned but it also makes tests pass
var memory = buffer.First;
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++;
// Fast path for single buffer
pBuffers[0] = Libuv.buf_init(
(IntPtr)memoryHandle.PinnedPointer,
memory.Length);
}
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;
Expand Down

0 comments on commit 39819d6

Please sign in to comment.