Skip to content
This repository has been archived by the owner on Dec 18, 2018. It is now read-only.

Commit

Permalink
React to pipes in corefx (#2337)
Browse files Browse the repository at this point in the history
  • Loading branch information
pakrym authored Feb 28, 2018
1 parent a391126 commit 2c108d9
Show file tree
Hide file tree
Showing 68 changed files with 715 additions and 258 deletions.
2 changes: 2 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,7 @@
<PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<LangVersion>latest</LangVersion>
<!-- https://github.com/aspnet/KestrelHttpServer/issues/2350 -->
<EnableApiCheck>false</EnableApiCheck>
</PropertyGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,21 @@
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Performance.Mocks;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;

namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
public class Http1ConnectionParsingOverheadBenchmark
{
private const int InnerLoopCount = 512;

public ReadOnlyBuffer<byte> _buffer;
public ReadOnlySequence<byte> _buffer;
public Http1Connection _http1Connection;

[IterationSetup]
public void Setup()
{
var memoryPool = new MemoryPool();
var memoryPool = KestrelMemoryPool.Create();
var pair = DuplexPipe.CreateConnectionPair(memoryPool);

var serviceContext = new ServiceContext
Expand Down
60 changes: 33 additions & 27 deletions benchmarks/Kestrel.Performance/Http1WritingBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
using Microsoft.AspNetCore.Testing;

namespace Microsoft.AspNetCore.Server.Kestrel.Performance
Expand All @@ -24,15 +25,17 @@ public class Http1WritingBenchmark
private static readonly Task _psuedoAsyncTask = Task.FromResult(27);
private static readonly Func<object, Task> _psuedoAsyncTaskFunc = (obj) => _psuedoAsyncTask;

private readonly TestHttp1Connection _http1Connection;
private TestHttp1Connection _http1Connection;
private DuplexPipe.DuplexPipePair _pair;
private MemoryPool<byte> _memoryPool;

private readonly byte[] _writeData;
private readonly byte[] _writeData = Encoding.ASCII.GetBytes("Hello, World!");

public Http1WritingBenchmark()
[GlobalSetup]
public void GlobalSetup()
{
_memoryPool = KestrelMemoryPool.Create();
_http1Connection = MakeHttp1Connection();
_writeData = Encoding.ASCII.GetBytes("Hello, World!");
}

[Params(true, false)]
Expand Down Expand Up @@ -93,33 +96,30 @@ public Task WriteAsync()

private TestHttp1Connection MakeHttp1Connection()
{
using (var memoryPool = new MemoryPool())
{
var pair = DuplexPipe.CreateConnectionPair(memoryPool);
_pair = pair;
var pair = DuplexPipe.CreateConnectionPair(_memoryPool);
_pair = pair;

var serviceContext = new ServiceContext
{
DateHeaderValueManager = new DateHeaderValueManager(),
ServerOptions = new KestrelServerOptions(),
Log = new MockTrace(),
HttpParser = new HttpParser<Http1ParsingHandler>()
};
var serviceContext = new ServiceContext
{
DateHeaderValueManager = new DateHeaderValueManager(),
ServerOptions = new KestrelServerOptions(),
Log = new MockTrace(),
HttpParser = new HttpParser<Http1ParsingHandler>()
};

var http1Connection = new TestHttp1Connection(new Http1ConnectionContext
{
ServiceContext = serviceContext,
ConnectionFeatures = new FeatureCollection(),
MemoryPool = memoryPool,
Application = pair.Application,
Transport = pair.Transport
});
var http1Connection = new TestHttp1Connection(new Http1ConnectionContext
{
ServiceContext = serviceContext,
ConnectionFeatures = new FeatureCollection(),
MemoryPool = _memoryPool,
Application = pair.Application,
Transport = pair.Transport
});

http1Connection.Reset();
http1Connection.InitializeStreams(MessageBody.ZeroContentLengthKeepAlive);
http1Connection.Reset();
http1Connection.InitializeStreams(MessageBody.ZeroContentLengthKeepAlive);

return http1Connection;
}
return http1Connection;
}

[IterationCleanup]
Expand All @@ -138,5 +138,11 @@ public enum Startup
Sync,
Async
}

[GlobalCleanup]
public void Dispose()
{
_memoryPool?.Dispose();
}
}
}
4 changes: 2 additions & 2 deletions benchmarks/Kestrel.Performance/HttpParserBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ public class HttpParserBenchmark : IHttpRequestLineHandler, IHttpHeadersHandler
{
private readonly HttpParser<Adapter> _parser = new HttpParser<Adapter>();

private ReadOnlyBuffer<byte> _buffer;
private ReadOnlySequence<byte> _buffer;

[Benchmark(Baseline = true, OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
public void PlaintextTechEmpower()
Expand Down Expand Up @@ -46,7 +46,7 @@ public void Unicode()

private void InsertData(byte[] data)
{
_buffer = new ReadOnlyBuffer<byte>(data);
_buffer = new ReadOnlySequence<byte>(data);
}

private void ParseData()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;

namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
Expand Down Expand Up @@ -78,7 +79,7 @@ public object GetViaGeneric_NotFound()

public HttpProtocolFeatureCollection()
{
var memoryPool = new MemoryPool();
var memoryPool = KestrelMemoryPool.Create();
var pair = DuplexPipe.CreateConnectionPair(memoryPool);

var serviceContext = new ServiceContext
Expand Down
4 changes: 2 additions & 2 deletions benchmarks/Kestrel.Performance/Mocks/NullParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ public class NullParser<TRequestHandler> : IHttpParser<TRequestHandler> where TR

public static readonly NullParser<Http1ParsingHandler> Instance = new NullParser<Http1ParsingHandler>();

public bool ParseHeaders(TRequestHandler handler, ReadOnlyBuffer<byte> buffer, out SequencePosition consumed, out SequencePosition examined, out int consumedBytes)
public bool ParseHeaders(TRequestHandler handler, ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined, out int consumedBytes)
{
handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue));
handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue));
Expand All @@ -35,7 +35,7 @@ public bool ParseHeaders(TRequestHandler handler, ReadOnlyBuffer<byte> buffer, o
return true;
}

public bool ParseRequestLine(TRequestHandler handler, ReadOnlyBuffer<byte> buffer, out SequencePosition consumed, out SequencePosition examined)
public bool ParseRequestLine(TRequestHandler handler, ReadOnlySequence<byte> buffer, out SequencePosition consumed, out SequencePosition examined)
{
handler.OnStartLine(HttpMethod.Get,
HttpVersion.Http11,
Expand Down
12 changes: 10 additions & 2 deletions benchmarks/Kestrel.Performance/PipeThroughputBenchmark.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
// 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.Buffers;
using System.IO.Pipelines;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;

namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
Expand All @@ -14,12 +16,12 @@ public class PipeThroughputBenchmark
private const int InnerLoopCount = 512;

private Pipe _pipe;
private MemoryPool _memoryPool;
private MemoryPool<byte> _memoryPool;

[IterationSetup]
public void Setup()
{
_memoryPool = new MemoryPool();
_memoryPool = KestrelMemoryPool.Create();
_pipe = new Pipe(new PipeOptions(_memoryPool));
}

Expand Down Expand Up @@ -62,5 +64,11 @@ public void ParseLiveAspNetInline()
_pipe.Reader.AdvanceTo(result.Buffer.End, result.Buffer.End);
}
}

[IterationCleanup]
public void Cleanup()
{
_memoryPool.Dispose();
}
}
}
18 changes: 14 additions & 4 deletions benchmarks/Kestrel.Performance/RequestParsingBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,23 @@
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Performance.Mocks;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;

namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
public class RequestParsingBenchmark
{
private MemoryPool<byte> _memoryPool;

public Pipe Pipe { get; set; }

public Http1Connection Http1Connection { get; set; }

[IterationSetup]
public void Setup()
{
var memoryPool = new MemoryPool();
var pair = DuplexPipe.CreateConnectionPair(memoryPool);
_memoryPool = KestrelMemoryPool.Create();
var pair = DuplexPipe.CreateConnectionPair(_memoryPool);

var serviceContext = new ServiceContext
{
Expand All @@ -36,7 +39,7 @@ public void Setup()
{
ServiceContext = serviceContext,
ConnectionFeatures = new FeatureCollection(),
MemoryPool = memoryPool,
MemoryPool = _memoryPool,
Application = pair.Application,
Transport = pair.Transport,
TimeoutControl = new MockTimeoutControl()
Expand All @@ -45,7 +48,7 @@ public void Setup()
http1Connection.Reset();

Http1Connection = http1Connection;
Pipe = new Pipe(new PipeOptions(memoryPool));
Pipe = new Pipe(new PipeOptions(_memoryPool));
}

[Benchmark(Baseline = true, OperationsPerInvoke = RequestParsingData.InnerLoopCount)]
Expand Down Expand Up @@ -201,5 +204,12 @@ private void ParseData()
}
while (true);
}


[IterationCleanup]
public void Cleanup()
{
_memoryPool.Dispose();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;

namespace Microsoft.AspNetCore.Server.Kestrel.Performance
{
Expand Down Expand Up @@ -170,7 +171,7 @@ private void Unknown(int count)
[IterationSetup]
public void Setup()
{
var memoryPool = new MemoryPool();
var memoryPool = KestrelMemoryPool.Create();
var pair = DuplexPipe.CreateConnectionPair(memoryPool);

var serviceContext = new ServiceContext
Expand Down
15 changes: 12 additions & 3 deletions benchmarks/Kestrel.Performance/ResponseHeadersWritingBenchmark.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
using Microsoft.AspNetCore.Server.Kestrel.Performance.Mocks;
using Microsoft.AspNetCore.Server.Kestrel.Transport.Abstractions.Internal;
using Microsoft.AspNetCore.Testing;

namespace Microsoft.AspNetCore.Server.Kestrel.Performance
Expand All @@ -23,6 +24,8 @@ public class ResponseHeadersWritingBenchmark

private TestHttp1Connection _http1Connection;

private MemoryPool<byte> _memoryPool;

[Params(
BenchmarkTypes.TechEmpowerPlaintext,
BenchmarkTypes.PlaintextChunked,
Expand Down Expand Up @@ -110,8 +113,8 @@ private Task PlaintextChunkedWithCookie()
[IterationSetup]
public void Setup()
{
var memoryPool = new MemoryPool();
var pair = DuplexPipe.CreateConnectionPair(memoryPool);
_memoryPool = KestrelMemoryPool.Create();
var pair = DuplexPipe.CreateConnectionPair(_memoryPool);

var serviceContext = new ServiceContext
{
Expand All @@ -125,7 +128,7 @@ public void Setup()
{
ServiceContext = serviceContext,
ConnectionFeatures = new FeatureCollection(),
MemoryPool = memoryPool,
MemoryPool = _memoryPool,
TimeoutControl = new MockTimeoutControl(),
Application = pair.Application,
Transport = pair.Transport
Expand All @@ -136,6 +139,12 @@ public void Setup()
_http1Connection = http1Connection;
}

[IterationCleanup]
public void Cleanup()
{
_memoryPool.Dispose();
}

public enum BenchmarkTypes
{
TechEmpowerPlaintext,
Expand Down
Loading

0 comments on commit 2c108d9

Please sign in to comment.