parent
5743d740b4
commit
13519b6079
|
|
@ -1,4 +1,4 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
<Import Project="..\..\build\common.props" />
|
<Import Project="..\..\build\common.props" />
|
||||||
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
<TargetFramework>netcoreapp1.1</TargetFramework>
|
<TargetFramework>netcoreapp1.1</TargetFramework>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<ServerGarbageCollection>true</ServerGarbageCollection>
|
<ServerGarbageCollection>true</ServerGarbageCollection>
|
||||||
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<IsPackable>false</IsPackable>
|
<IsPackable>false</IsPackable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -95,7 +95,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
private void InsertData(byte[] bytes)
|
private void InsertData(byte[] bytes)
|
||||||
{
|
{
|
||||||
var buffer = Pipe.Writer.Alloc(2048);
|
var buffer = Pipe.Writer.Alloc(2048);
|
||||||
buffer.Write(bytes);
|
buffer.WriteFast(bytes);
|
||||||
// There should not be any backpressure and task completes immediately
|
// There should not be any backpressure and task completes immediately
|
||||||
buffer.FlushAsync().GetAwaiter().GetResult();
|
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