Add benchmarks for Frame writes.
This commit is contained in:
parent
f467c42f54
commit
51ecbd7949
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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": {
|
||||
|
|
|
|||
|
|
@ -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>()
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue