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\LifetimeNotImplemented.cs = test\shared\LifetimeNotImplemented.cs
|
||||||
test\shared\MockConnection.cs = test\shared\MockConnection.cs
|
test\shared\MockConnection.cs = test\shared\MockConnection.cs
|
||||||
test\shared\MockFrameControl.cs = test\shared\MockFrameControl.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\MockSystemClock.cs = test\shared\MockSystemClock.cs
|
||||||
test\shared\SocketInputExtensions.cs = test\shared\SocketInputExtensions.cs
|
test\shared\SocketInputExtensions.cs = test\shared\SocketInputExtensions.cs
|
||||||
test\shared\TestApplicationErrorLogger.cs = test\shared\TestApplicationErrorLogger.cs
|
test\shared\TestApplicationErrorLogger.cs = test\shared\TestApplicationErrorLogger.cs
|
||||||
test\shared\TestConnection.cs = test\shared\TestConnection.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\TestKestrelTrace.cs = test\shared\TestKestrelTrace.cs
|
||||||
test\shared\TestServer.cs = test\shared\TestServer.cs
|
test\shared\TestServer.cs = test\shared\TestServer.cs
|
||||||
test\shared\TestServiceContext.cs = test\shared\TestServiceContext.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.
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using BenchmarkDotNet.Environments;
|
|
||||||
using BenchmarkDotNet.Jobs;
|
|
||||||
using BenchmarkDotNet.Properties;
|
|
||||||
using BenchmarkDotNet.Running;
|
using BenchmarkDotNet.Running;
|
||||||
using BenchmarkDotNet.Toolchains;
|
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
{
|
{
|
||||||
|
|
@ -36,6 +32,10 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||||
{
|
{
|
||||||
BenchmarkRunner.Run<RequestParsing>();
|
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
|
public enum BenchmarkType : uint
|
||||||
{
|
{
|
||||||
RequestParsing = 1,
|
RequestParsing = 1,
|
||||||
|
Writing = 2,
|
||||||
// add new ones in powers of two - e.g. 2,4,8,16...
|
// add new ones in powers of two - e.g. 2,4,8,16...
|
||||||
|
|
||||||
All = uint.MaxValue
|
All = uint.MaxValue
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
To run a specific benchmark add it as parameter
|
To run a specific benchmark add it as parameter
|
||||||
```
|
```
|
||||||
dotnet run RequestParsing
|
dotnet run -c Release RequestParsing
|
||||||
```
|
```
|
||||||
To run all use `All` as parameter
|
To run all use `All` as parameter
|
||||||
```
|
```
|
||||||
dotnet run All
|
dotnet run -c Release All
|
||||||
```
|
```
|
||||||
Using no parameter will list all available benchmarks
|
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-*",
|
"version": "1.0.0-*",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"BenchmarkDotNet": "0.10.0",
|
"BenchmarkDotNet": "0.10.1",
|
||||||
"Microsoft.AspNetCore.Server.Kestrel": "1.2.0-*"
|
"Microsoft.AspNetCore.Server.Kestrel": "1.2.0-*",
|
||||||
|
"Moq": "4.6.36-*"
|
||||||
},
|
},
|
||||||
"frameworks": {
|
"frameworks": {
|
||||||
"netcoreapp1.0": {
|
"netcoreapp1.1": {
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"Microsoft.NETCore.App": {
|
"Microsoft.NETCore.App": {
|
||||||
"version": "1.0.1-*",
|
"version": "1.1.0-*",
|
||||||
"type": "platform"
|
"type": "platform"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -18,16 +19,18 @@
|
||||||
"emitEntryPoint": true,
|
"emitEntryPoint": true,
|
||||||
"compile": {
|
"compile": {
|
||||||
"include": [
|
"include": [
|
||||||
"../shared/SocketInputExtensions.cs",
|
|
||||||
"../shared/TestKestrelTrace.cs",
|
|
||||||
"../shared/TestApplicationErrorLogger.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",
|
"keyFile": "../../tools/Key.snk",
|
||||||
"copyToOutput": {
|
"copyToOutput": {
|
||||||
"include": "TestResources/testCert.pfx"
|
"include": "TestResources/testCert.pfx"
|
||||||
}
|
},
|
||||||
},
|
},
|
||||||
"runtimeOptions": {
|
"runtimeOptions": {
|
||||||
"configProperties": {
|
"configProperties": {
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,6 @@ using Microsoft.AspNetCore.Server.Kestrel;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Server.KestrelTests.TestHelpers;
|
|
||||||
using Microsoft.AspNetCore.Testing;
|
using Microsoft.AspNetCore.Testing;
|
||||||
using Microsoft.Extensions.Internal;
|
using Microsoft.Extensions.Internal;
|
||||||
using Moq;
|
using Moq;
|
||||||
|
|
@ -47,7 +46,7 @@ namespace Microsoft.AspNetCore.Server.KestrelTests
|
||||||
_connectionContext = new ConnectionContext(listenerContext)
|
_connectionContext = new ConnectionContext(listenerContext)
|
||||||
{
|
{
|
||||||
Input = _socketInput,
|
Input = _socketInput,
|
||||||
Output = new MockSocketOuptut(),
|
Output = new MockSocketOutput(),
|
||||||
ConnectionControl = Mock.Of<IConnectionControl>()
|
ConnectionControl = Mock.Of<IConnectionControl>()
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ using Microsoft.AspNetCore.Server.Kestrel.Internal.Http;
|
||||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
|
using Microsoft.AspNetCore.Server.Kestrel.Internal.Infrastructure;
|
||||||
using Microsoft.Extensions.Internal;
|
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)
|
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