parent
5743d740b4
commit
13519b6079
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue