Add benchmarks for Frame writes.

This commit is contained in:
Cesar Blum Silveira 2016-12-07 17:34:01 -08:00
parent f467c42f54
commit 51ecbd7949
8 changed files with 162 additions and 18 deletions

View File

@ -39,10 +39,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "shared", "shared", "{0EF2AC
test\shared\LifetimeNotImplemented.cs = test\shared\LifetimeNotImplemented.cs
test\shared\MockConnection.cs = test\shared\MockConnection.cs
test\shared\MockFrameControl.cs = test\shared\MockFrameControl.cs
test\shared\MockSocketOutput.cs = test\shared\MockSocketOutput.cs
test\shared\MockSystemClock.cs = test\shared\MockSystemClock.cs
test\shared\SocketInputExtensions.cs = test\shared\SocketInputExtensions.cs
test\shared\TestApplicationErrorLogger.cs = test\shared\TestApplicationErrorLogger.cs
test\shared\TestConnection.cs = test\shared\TestConnection.cs
test\shared\TestFrame.cs = test\shared\TestFrame.cs
test\shared\TestKestrelTrace.cs = test\shared\TestKestrelTrace.cs
test\shared\TestServer.cs = test\shared\TestServer.cs
test\shared\TestServiceContext.cs = test\shared\TestServiceContext.cs

View File

@ -2,11 +2,7 @@
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using BenchmarkDotNet.Environments;
using BenchmarkDotNet.Jobs;
using BenchmarkDotNet.Properties;
using BenchmarkDotNet.Running;
using BenchmarkDotNet.Toolchains;
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
@ -36,6 +32,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
BenchmarkRunner.Run<RequestParsing>();
}
if (type.HasFlag(BenchmarkType.Writing))
{
BenchmarkRunner.Run<Writing>();
}
}
}
@ -43,6 +43,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
public enum BenchmarkType : uint
{
RequestParsing = 1,
Writing = 2,
// add new ones in powers of two - e.g. 2,4,8,16...
All = uint.MaxValue

View File

@ -2,10 +2,10 @@
To run a specific benchmark add it as parameter
```
dotnet run RequestParsing
dotnet run -c Release RequestParsing
```
To run all use `All` as parameter
```
dotnet run All
dotnet run -c Release All
```
Using no parameter will list all available benchmarks

View File

@ -0,0 +1,117 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Threading;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Server.Kestrel.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.AspNetCore.Testing;
using Moq;
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
public class Writing
{
private readonly TestFrame<object> _frame;
private readonly TestFrame<object> _frameChunked;
private readonly byte[] _writeData;
public Writing()
{
_frame = MakeFrame();
_frameChunked = MakeFrame();
_writeData = new byte[1];
}
[Setup]
public void Setup()
{
_frame.Reset();
_frame.RequestHeaders.Add("Content-Length", "1073741824");
_frameChunked.Reset();
_frameChunked.RequestHeaders.Add("Transfer-Encoding", "chunked");
}
[Benchmark]
public void Write()
{
_frame.Write(new ArraySegment<byte>(_writeData));
}
[Benchmark]
public void WriteChunked()
{
_frameChunked.Write(new ArraySegment<byte>(_writeData));
}
[Benchmark]
public async Task WriteAsync()
{
await _frame.WriteAsync(new ArraySegment<byte>(_writeData), default(CancellationToken));
}
[Benchmark]
public async Task WriteAsyncChunked()
{
await _frameChunked.WriteAsync(new ArraySegment<byte>(_writeData), default(CancellationToken));
}
[Benchmark]
public async Task WriteAsyncAwaited()
{
await _frame.WriteAsyncAwaited(new ArraySegment<byte>(_writeData), default(CancellationToken));
}
[Benchmark]
public async Task WriteAsyncAwaitedChunked()
{
await _frameChunked.WriteAsyncAwaited(new ArraySegment<byte>(_writeData), default(CancellationToken));
}
[Benchmark]
public async Task ProduceEnd()
{
await _frame.ProduceEndAsync();
}
[Benchmark]
public async Task ProduceEndChunked()
{
await _frameChunked.ProduceEndAsync();
}
private TestFrame<object> MakeFrame()
{
var ltp = new LoggingThreadPool(Mock.Of<IKestrelTrace>());
var pool = new MemoryPool();
var socketInput = new SocketInput(pool, ltp);
var serviceContext = new ServiceContext
{
DateHeaderValueManager = new DateHeaderValueManager(),
ServerOptions = new KestrelServerOptions(),
Log = Mock.Of<IKestrelTrace>()
};
var listenerContext = new ListenerContext(serviceContext)
{
ServerAddress = ServerAddress.FromUrl("http://localhost:5000")
};
var connectionContext = new ConnectionContext(listenerContext)
{
Input = socketInput,
Output = new MockSocketOutput(),
ConnectionControl = Mock.Of<IConnectionControl>()
};
var frame = new TestFrame<object>(application: null, context: connectionContext);
frame.Reset();
frame.InitializeHeaders();
return frame;
}
}
}

View File

@ -1,14 +1,15 @@
{
"version": "1.0.0-*",
"dependencies": {
"BenchmarkDotNet": "0.10.0",
"Microsoft.AspNetCore.Server.Kestrel": "1.2.0-*"
"BenchmarkDotNet": "0.10.1",
"Microsoft.AspNetCore.Server.Kestrel": "1.2.0-*",
"Moq": "4.6.36-*"
},
"frameworks": {
"netcoreapp1.0": {
"netcoreapp1.1": {
"dependencies": {
"Microsoft.NETCore.App": {
"version": "1.0.1-*",
"version": "1.1.0-*",
"type": "platform"
}
}
@ -18,16 +19,18 @@
"emitEntryPoint": true,
"compile": {
"include": [
"../shared/SocketInputExtensions.cs",
"../shared/TestKestrelTrace.cs",
"../shared/TestApplicationErrorLogger.cs",
"../shared/MockConnection.cs"
"../shared/TestFrame.cs",
"../shared/TestKestrelTrace.cs",
"../shared/MockConnection.cs",
"../shared/MockSocketOutput.cs",
"../shared/SocketInputExtensions.cs"
]
},
"keyFile": "../../tools/Key.snk",
"copyToOutput": {
"include": "TestResources/testCert.pfx"
}
},
},
"runtimeOptions": {
"configProperties": {

View File

@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Server.Kestrel;
using Microsoft.AspNetCore.Server.Kestrel.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.AspNetCore.Server.KestrelTests.TestHelpers;
using Microsoft.AspNetCore.Testing;
using Microsoft.Extensions.Internal;
using Moq;
@ -47,7 +46,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
_connectionContext = new ConnectionContext(listenerContext)
{
Input = _socketInput,
Output = new MockSocketOuptut(),
Output = new MockSocketOutput(),
ConnectionControl = Mock.Of<IConnectionControl>()
};

View File

@ -8,9 +8,9 @@ using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
using Microsoft.Extensions.Internal;
namespace Microsoft.AspNetCore.Server.KestrelTests.TestHelpers
namespace Microsoft.AspNetCore.Testing
{
public class MockSocketOuptut : ISocketOutput
public class MockSocketOutput : ISocketOutput
{
public void ProducingComplete(MemoryPoolIterator end)
{

22
test/shared/TestFrame.cs Normal file
View File

@ -0,0 +1,22 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting.Server;
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
namespace Microsoft.AspNetCore.Testing
{
public class TestFrame<TContext> : Frame<TContext>
{
public TestFrame(IHttpApplication<TContext> application, ConnectionContext context)
: base(application, context)
{
}
public Task ProduceEndAsync()
{
return ProduceEnd();
}
}
}