Last active
December 9, 2018 04:08
-
-
Save benaadams/77b3cba47261beadc94cc9fcb6d5ebd4 to your computer and use it in GitHub Desktop.
PipeThroughputBenchmark
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
SET COMPlus_TieredCompilation=0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System; | |
using System.Buffers; | |
using System.IO.Pipelines; | |
using System.Threading.Tasks; | |
using BenchmarkDotNet.Attributes; | |
using BenchmarkDotNet.Running; | |
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal; | |
public class PipeThroughputBenchmark | |
{ | |
// 128 (min Length) * InnerLoopCount > _memoryPool.MaxBufferSize | |
private const int InnerLoopCount = 33; | |
private PipeReader _reader; | |
private PipeWriter _writer; | |
private MemoryPool<byte> _memoryPool; | |
[GlobalSetup] | |
public void Setup() | |
{ | |
_memoryPool = KestrelMemoryPool.Create(); | |
var chunkLength = Length / Chunks; | |
if (chunkLength > _memoryPool.MaxBufferSize) | |
{ | |
// Parallel test will deadlock if too large (waiting for second Task to complete), so N/A that run | |
throw new InvalidOperationException(); | |
} | |
if (Length != chunkLength * Chunks) | |
{ | |
// Test will deadlock waiting for data so N/A that run | |
throw new InvalidOperationException(); | |
} | |
var pipe = new Pipe(new PipeOptions(_memoryPool)); | |
_reader = pipe.Reader; | |
_writer = pipe.Writer; | |
} | |
[Params(1, 2, 4, 8)] | |
public int Chunks { get; set; } | |
[Params(128, 256, 1024, 2048, 4096, 8192)] | |
public int Length { get; set; } | |
[Benchmark(OperationsPerInvoke = InnerLoopCount)] | |
public Task Parse_ParallelAsync() | |
{ | |
return Parse_ParallelAsyncImpl(); | |
} | |
private Task Parse_ParallelAsyncImpl() | |
{ | |
var writing = Task.Run(async () => | |
{ | |
var chunks = Chunks; | |
var chunkLength = Length / chunks; | |
for (int i = 0; i < InnerLoopCount; i++) | |
{ | |
for (var c = 0; c < chunks; c++) | |
{ | |
_writer.GetMemory(chunkLength); | |
_writer.Advance(chunkLength); | |
await _writer.FlushAsync(); | |
} | |
} | |
}); | |
var reading = Task.Run(async () => | |
{ | |
long remaining = InnerLoopCount * Length; | |
while (remaining != 0) | |
{ | |
var result = await _reader.ReadAsync(); | |
remaining -= result.Buffer.Length; | |
_reader.AdvanceTo(result.Buffer.End, result.Buffer.End); | |
} | |
}); | |
return Task.WhenAll(writing, reading); | |
} | |
[Benchmark(OperationsPerInvoke = InnerLoopCount)] | |
public Task Parse_SequentialAsync() | |
{ | |
return Parse_SequentialAsyncImpl(); | |
} | |
private async Task Parse_SequentialAsyncImpl() | |
{ | |
var chunks = Chunks; | |
var chunkLength = Length / chunks; | |
for (int i = 0; i < InnerLoopCount; i++) | |
{ | |
for (var c = 0; c < chunks; c++) | |
{ | |
_writer.GetMemory(chunkLength); | |
_writer.Advance(chunkLength); | |
await _writer.FlushAsync(); | |
} | |
var result = await _reader.ReadAsync(); | |
_reader.AdvanceTo(result.Buffer.End, result.Buffer.End); | |
} | |
} | |
[GlobalCleanup] | |
public void Cleanup() | |
{ | |
_memoryPool.Dispose(); | |
} | |
public static void Main(string[] args) | |
{ | |
var summary = BenchmarkSwitcher.FromAssembly(typeof(PipeThroughputBenchmark).Assembly).Run(args); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<Project Sdk="Microsoft.NET.Sdk"> | |
<PropertyGroup> | |
<OutputType>Exe</OutputType> | |
<TargetFramework>netcoreapp3.0</TargetFramework> | |
</PropertyGroup> | |
<ItemGroup> | |
<PackageReference Include="BenchmarkDotNet" Version="0.11.3" /> | |
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.2.0" /> | |
<PackageReference Include="System.IO.Pipelines" Version="4.5.2" /> | |
</ItemGroup> | |
</Project> |
Author
benaadams
commented
Dec 8, 2018
•
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment