Fix CopyTo implementation in benchmark. (#1462)

* wip

* ooops
This commit is contained in:
David Fowler 2017-03-07 17:39:56 -08:00 committed by GitHub
parent 5743d740b4
commit 13519b6079
3 changed files with 66 additions and 2 deletions

View File

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\build\common.props" />
@ -6,6 +6,7 @@
<TargetFramework>netcoreapp1.1</TargetFramework>
<OutputType>Exe</OutputType>
<ServerGarbageCollection>true</ServerGarbageCollection>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<IsPackable>false</IsPackable>
</PropertyGroup>

View File

@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
private void InsertData(byte[] bytes)
{
var buffer = Pipe.Writer.Alloc(2048);
buffer.Write(bytes);
buffer.WriteFast(bytes);
// There should not be any backpressure and task completes immediately
buffer.FlushAsync().GetAwaiter().GetResult();
}

View File

@ -0,0 +1,63 @@
using System;
using System.Collections.Generic;
using System.IO.Pipelines;
using System.Text;
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
internal static class WritableBufferExtensions
{
public static void WriteFast(this WritableBuffer buffer, ReadOnlySpan<byte> source)
{
if (buffer.Memory.IsEmpty)
{
buffer.Ensure();
}
// Fast path, try copying to the available memory directly
if (source.Length <= buffer.Memory.Length)
{
source.CopyToFast(buffer.Memory.Span);
buffer.Advance(source.Length);
return;
}
var remaining = source.Length;
var offset = 0;
while (remaining > 0)
{
var writable = Math.Min(remaining, buffer.Memory.Length);
buffer.Ensure(writable);
if (writable == 0)
{
continue;
}
source.Slice(offset, writable).CopyToFast(buffer.Memory.Span);
remaining -= writable;
offset += writable;
buffer.Advance(writable);
}
}
private unsafe static void CopyToFast(this ReadOnlySpan<byte> source, Span<byte> destination)
{
if (destination.Length < source.Length)
{
throw new InvalidOperationException();
}
// Assume it fits
fixed (byte* pSource = &source.DangerousGetPinnableReference())
fixed (byte* pDest = &destination.DangerousGetPinnableReference())
{
Buffer.MemoryCopy(pSource, pDest, destination.Length, source.Length);
}
}
}
}