FrameFeatureCollection benchmark (#1643)
This commit is contained in:
parent
fb22629da6
commit
2863cca8ca
|
|
@ -63,7 +63,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
_currentIHttpSendFileFeature = null;
|
||||
}
|
||||
|
||||
private object FastFeatureGet(Type key)
|
||||
internal object FastFeatureGet(Type key)
|
||||
{
|
||||
if (key == IHttpRequestFeatureType)
|
||||
{
|
||||
|
|
@ -132,7 +132,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
return ExtraFeatureGet(key);
|
||||
}
|
||||
|
||||
private void FastFeatureSet(Type key, object feature)
|
||||
internal void FastFeatureSet(Type key, object feature)
|
||||
{
|
||||
_featureRevision++;
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,107 @@
|
|||
// 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 BenchmarkDotNet.Attributes;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||
{
|
||||
[Config(typeof(CoreConfig))]
|
||||
public class FrameFeatureCollection
|
||||
{
|
||||
private readonly Frame<object> _frame;
|
||||
private IFeatureCollection _collection;
|
||||
|
||||
[Benchmark(Baseline = true)]
|
||||
public IHttpRequestFeature GetFirstViaFastFeature()
|
||||
{
|
||||
return (IHttpRequestFeature)GetFastFeature(typeof(IHttpRequestFeature));
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IHttpRequestFeature GetFirstViaType()
|
||||
{
|
||||
return (IHttpRequestFeature)Get(typeof(IHttpRequestFeature));
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IHttpRequestFeature GetFirstViaExtension()
|
||||
{
|
||||
return _collection.GetType<IHttpRequestFeature>();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IHttpRequestFeature GetFirstViaGeneric()
|
||||
{
|
||||
return _collection.Get<IHttpRequestFeature>();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IHttpSendFileFeature GetLastViaFastFeature()
|
||||
{
|
||||
return (IHttpSendFileFeature)GetFastFeature(typeof(IHttpSendFileFeature));
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IHttpSendFileFeature GetLastViaType()
|
||||
{
|
||||
return (IHttpSendFileFeature)Get(typeof(IHttpSendFileFeature));
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IHttpSendFileFeature GetLastViaExtension()
|
||||
{
|
||||
return _collection.GetType<IHttpSendFileFeature>();
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public IHttpSendFileFeature GetLastViaGeneric()
|
||||
{
|
||||
return _collection.Get<IHttpSendFileFeature> ();
|
||||
}
|
||||
|
||||
private object Get(Type type)
|
||||
{
|
||||
return _collection[type];
|
||||
}
|
||||
|
||||
private object GetFastFeature(Type type)
|
||||
{
|
||||
return _frame.FastFeatureGet(type);
|
||||
}
|
||||
|
||||
public FrameFeatureCollection()
|
||||
{
|
||||
var serviceContext = new ServiceContext
|
||||
{
|
||||
HttpParserFactory = _ => NullParser.Instance,
|
||||
ServerOptions = new KestrelServerOptions()
|
||||
};
|
||||
var frameContext = new FrameContext
|
||||
{
|
||||
ServiceContext = serviceContext,
|
||||
ConnectionInformation = new MockConnectionInformation()
|
||||
};
|
||||
|
||||
_frame = new Frame<object>(application: null, frameContext: frameContext);
|
||||
}
|
||||
|
||||
[Setup]
|
||||
public void Setup()
|
||||
{
|
||||
_collection = _frame;
|
||||
}
|
||||
|
||||
}
|
||||
public static class IFeatureCollectionExtensions
|
||||
{
|
||||
public static T GetType<T>(this IFeatureCollection collection)
|
||||
{
|
||||
return (T)collection[typeof(T)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,12 +1,10 @@
|
|||
// 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.Text;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
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.Internal.System;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||
|
|
@ -100,52 +98,5 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
|||
ErrorUtilities.ThrowInvalidRequestHeaders();
|
||||
}
|
||||
}
|
||||
|
||||
private class NullParser : IHttpParser
|
||||
{
|
||||
private readonly byte[] _startLine = Encoding.ASCII.GetBytes("GET /plaintext HTTP/1.1\r\n");
|
||||
private readonly byte[] _target = Encoding.ASCII.GetBytes("/plaintext");
|
||||
private readonly byte[] _hostHeaderName = Encoding.ASCII.GetBytes("Host");
|
||||
private readonly byte[] _hostHeaderValue = Encoding.ASCII.GetBytes("www.example.com");
|
||||
private readonly byte[] _acceptHeaderName = Encoding.ASCII.GetBytes("Accept");
|
||||
private readonly byte[] _acceptHeaderValue = Encoding.ASCII.GetBytes("text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7\r\n\r\n");
|
||||
private readonly byte[] _connectionHeaderName = Encoding.ASCII.GetBytes("Connection");
|
||||
private readonly byte[] _connectionHeaderValue = Encoding.ASCII.GetBytes("keep-alive");
|
||||
|
||||
public static readonly NullParser Instance = new NullParser();
|
||||
|
||||
public bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes)
|
||||
{
|
||||
handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue));
|
||||
handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue));
|
||||
handler.OnHeader(new Span<byte>(_connectionHeaderName), new Span<byte>(_connectionHeaderValue));
|
||||
|
||||
consumedBytes = 0;
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
{
|
||||
handler.OnStartLine(HttpMethod.Get,
|
||||
HttpVersion.Http11,
|
||||
new Span<byte>(_target),
|
||||
new Span<byte>(_target),
|
||||
Span<byte>.Empty,
|
||||
Span<byte>.Empty,
|
||||
false);
|
||||
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
// 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.Text;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System;
|
||||
using Microsoft.AspNetCore.Server.Kestrel.Internal.System.IO.Pipelines;
|
||||
|
||||
namespace Microsoft.AspNetCore.Server.Kestrel.Performance
|
||||
{
|
||||
public class NullParser : IHttpParser
|
||||
{
|
||||
private readonly byte[] _startLine = Encoding.ASCII.GetBytes("GET /plaintext HTTP/1.1\r\n");
|
||||
private readonly byte[] _target = Encoding.ASCII.GetBytes("/plaintext");
|
||||
private readonly byte[] _hostHeaderName = Encoding.ASCII.GetBytes("Host");
|
||||
private readonly byte[] _hostHeaderValue = Encoding.ASCII.GetBytes("www.example.com");
|
||||
private readonly byte[] _acceptHeaderName = Encoding.ASCII.GetBytes("Accept");
|
||||
private readonly byte[] _acceptHeaderValue = Encoding.ASCII.GetBytes("text/plain,text/html;q=0.9,application/xhtml+xml;q=0.9,application/xml;q=0.8,*/*;q=0.7\r\n\r\n");
|
||||
private readonly byte[] _connectionHeaderName = Encoding.ASCII.GetBytes("Connection");
|
||||
private readonly byte[] _connectionHeaderValue = Encoding.ASCII.GetBytes("keep-alive");
|
||||
|
||||
public static readonly NullParser Instance = new NullParser();
|
||||
|
||||
public bool ParseHeaders(IHttpHeadersHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined, out int consumedBytes)
|
||||
{
|
||||
handler.OnHeader(new Span<byte>(_hostHeaderName), new Span<byte>(_hostHeaderValue));
|
||||
handler.OnHeader(new Span<byte>(_acceptHeaderName), new Span<byte>(_acceptHeaderValue));
|
||||
handler.OnHeader(new Span<byte>(_connectionHeaderName), new Span<byte>(_connectionHeaderValue));
|
||||
|
||||
consumedBytes = 0;
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool ParseRequestLine(IHttpRequestLineHandler handler, ReadableBuffer buffer, out ReadCursor consumed, out ReadCursor examined)
|
||||
{
|
||||
handler.OnStartLine(HttpMethod.Get,
|
||||
HttpVersion.Http11,
|
||||
new Span<byte>(_target),
|
||||
new Span<byte>(_target),
|
||||
Span<byte>.Empty,
|
||||
Span<byte>.Empty,
|
||||
false);
|
||||
|
||||
consumed = buffer.Start;
|
||||
examined = buffer.End;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -87,7 +87,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
_current{feature.Name} = null;")}
|
||||
}}
|
||||
|
||||
private object FastFeatureGet(Type key)
|
||||
internal object FastFeatureGet(Type key)
|
||||
{{{Each(allFeatures, feature => $@"
|
||||
if (key == {feature.Name}Type)
|
||||
{{
|
||||
|
|
@ -96,7 +96,7 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http
|
|||
return ExtraFeatureGet(key);
|
||||
}}
|
||||
|
||||
private void FastFeatureSet(Type key, object feature)
|
||||
internal void FastFeatureSet(Type key, object feature)
|
||||
{{
|
||||
_featureRevision++;
|
||||
{Each(allFeatures, feature => $@"
|
||||
|
|
|
|||
Loading…
Reference in New Issue