add some very simple, fairly stupid, benchmarks (#322)
This commit is contained in:
parent
e955c4b9aa
commit
28bf0b445b
|
|
@ -42,3 +42,4 @@ site.min.css
|
|||
signalr-client/
|
||||
dist/
|
||||
global.json
|
||||
BenchmarkDotNet.Artifacts/
|
||||
|
|
|
|||
|
|
@ -73,6 +73,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "client-ts", "client-ts", "{
|
|||
client-ts\package.json = client-ts\package.json
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Microsoft.AspNetCore.SignalR.Microbenchmarks", "test\Microsoft.AspNetCore.SignalR.Microbenchmarks\Microsoft.AspNetCore.SignalR.Microbenchmarks.csproj", "{96771B3F-4D18-41A7-A75B-FF38E76AAC89}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
|
@ -175,6 +177,10 @@ Global
|
|||
{333526A4-633B-491A-AC45-CC62A0012D1C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{333526A4-633B-491A-AC45-CC62A0012D1C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{333526A4-633B-491A-AC45-CC62A0012D1C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{96771B3F-4D18-41A7-A75B-FF38E76AAC89}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{96771B3F-4D18-41A7-A75B-FF38E76AAC89}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{96771B3F-4D18-41A7-A75B-FF38E76AAC89}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{96771B3F-4D18-41A7-A75B-FF38E76AAC89}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -205,5 +211,6 @@ Global
|
|||
{B0D32729-48AA-4841-B52A-2A61B60EED61} = {6A35B453-52EC-48AF-89CA-D4A69800F131}
|
||||
{333526A4-633B-491A-AC45-CC62A0012D1C} = {3A76C5A2-79ED-49BC-8BDC-6A3A766FFA1B}
|
||||
{6CEC3DC2-5B01-45A8-8F0D-8531315DA90B} = {6A35B453-52EC-48AF-89CA-D4A69800F131}
|
||||
{96771B3F-4D18-41A7-A75B-FF38E76AAC89} = {6A35B453-52EC-48AF-89CA-D4A69800F131}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
<ItemGroup>
|
||||
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.AspNetCore.SignalR.Test.Server\*.csproj" />
|
||||
<ExcludeFromTest Include="$(RepositoryRoot)test\WebSocketsTestApp\*.csproj" />
|
||||
<ExcludeFromTest Include="$(RepositoryRoot)test\Microsoft.AspNetCore.SignalR.Microbenchmarks\*.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectsToPack Include="$(RepositoryRoot)client-ts\Microsoft.AspNetCore.SignalR.Client.TS\*.csproj" />
|
||||
|
|
|
|||
|
|
@ -159,7 +159,7 @@ namespace Microsoft.AspNetCore.Sockets.Internal.Formatters
|
|||
else
|
||||
{
|
||||
// Copy as much as possible from the Unread buffer
|
||||
var toCopy = Math.Min(_state.Length, buffer.Unread.Length);
|
||||
var toCopy = Math.Min(_state.Length - _state.Read, buffer.Unread.Length);
|
||||
buffer.Unread.Slice(0, toCopy).CopyTo(_state.Payload.Slice(_state.Read));
|
||||
_state.Read += toCopy;
|
||||
buffer.Advance(toCopy);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
using System.Buffers;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Sequences;
|
||||
|
||||
namespace System
|
||||
{
|
||||
|
|
@ -11,6 +10,11 @@ namespace System
|
|||
{
|
||||
public static ReadOnlyBytes ToChunkedReadOnlyBytes(this byte[] data, int chunkSize)
|
||||
{
|
||||
if (chunkSize == 0)
|
||||
{
|
||||
return new ReadOnlyBytes(data);
|
||||
}
|
||||
|
||||
var chunks = new List<byte[]>();
|
||||
for (var i = 0; i < data.Length; i += chunkSize)
|
||||
{
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using BenchmarkDotNet.Columns;
|
||||
using BenchmarkDotNet.Configs;
|
||||
using BenchmarkDotNet.Diagnosers;
|
||||
using BenchmarkDotNet.Engines;
|
||||
using BenchmarkDotNet.Environments;
|
||||
using BenchmarkDotNet.Jobs;
|
||||
using BenchmarkDotNet.Validators;
|
||||
|
||||
namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||
{
|
||||
public class CoreConfig : ManualConfig
|
||||
{
|
||||
public CoreConfig()
|
||||
{
|
||||
Add(JitOptimizationsValidator.FailOnError);
|
||||
Add(MemoryDiagnoser.Default);
|
||||
Add(StatisticColumn.OperationsPerSecond);
|
||||
|
||||
Add(Job.Default
|
||||
.With(Runtime.Core)
|
||||
.WithRemoveOutliers(false)
|
||||
.With(new GcMode() { Server = true })
|
||||
.With(RunStrategy.Throughput)
|
||||
.WithLaunchCount(3)
|
||||
.WithWarmupCount(5)
|
||||
.WithTargetCount(10));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Buffers;
|
||||
using BenchmarkDotNet.Attributes;
|
||||
using Microsoft.AspNetCore.Sockets;
|
||||
using Microsoft.AspNetCore.Sockets.Internal.Formatters;
|
||||
using Microsoft.AspNetCore.Sockets.Tests.Internal;
|
||||
|
||||
namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||
{
|
||||
[Config(typeof(CoreConfig))]
|
||||
public class MessageParserBenchmark
|
||||
{
|
||||
private static readonly Random Random = new Random();
|
||||
private readonly MessageParser _parser = new MessageParser();
|
||||
private ReadOnlyBytes _input;
|
||||
private byte[] _buffer;
|
||||
|
||||
[Params(32, 64)]
|
||||
public int ChunkSize { get; set; }
|
||||
|
||||
[Params(64, 128)]
|
||||
public int MessageLength { get; set; }
|
||||
|
||||
[Params(MessageFormat.Text, MessageFormat.Binary)]
|
||||
public MessageFormat Format { get; set; }
|
||||
|
||||
[Setup]
|
||||
public void Setup()
|
||||
{
|
||||
_buffer = new byte[MessageLength];
|
||||
Random.NextBytes(_buffer);
|
||||
var message = new Message(_buffer, MessageType.Binary);
|
||||
var output = new ArrayOutput(MessageLength + 32);
|
||||
if (!MessageFormatter.TryWriteMessage(message, output, Format))
|
||||
{
|
||||
throw new InvalidOperationException("Failed to format message");
|
||||
}
|
||||
_input = output.ToArray().ToChunkedReadOnlyBytes(ChunkSize);
|
||||
}
|
||||
|
||||
[Benchmark]
|
||||
public void SingleBinaryMessage()
|
||||
{
|
||||
var reader = new BytesReader(_input);
|
||||
if (!_parser.TryParseMessage(ref reader, Format, out _))
|
||||
{
|
||||
throw new InvalidOperationException("Failed to parse");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<Import Project="..\..\build\common.props" />
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFrameworks>netcoreapp1.1</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Common\ByteArrayExtensions.cs" Link="ByteArrayExtensions.cs" />
|
||||
<Compile Include="..\Common\ArrayOutput.cs" Link="ArrayOutput.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Sockets.Common\Microsoft.AspNetCore.Sockets.Common.csproj" />
|
||||
<PackageReference Include="BenchmarkDotNet" Version="0.10.3" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
using System.Reflection;
|
||||
using BenchmarkDotNet.Running;
|
||||
|
||||
namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
|
||||
{
|
||||
class Program
|
||||
{
|
||||
static void Main(string[] args)
|
||||
{
|
||||
BenchmarkSwitcher.FromAssembly(typeof(Program).GetTypeInfo().Assembly).Run(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -66,9 +66,7 @@ namespace Microsoft.AspNetCore.Sockets.Common.Tests.Internal.Formatters
|
|||
/* body: */ 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x20, 0x45, 0x72, 0x72, 0x6F, 0x72
|
||||
};
|
||||
var parser = new MessageParser();
|
||||
var buffer = chunkSize > 0 ?
|
||||
encoded.ToChunkedReadOnlyBytes(chunkSize) :
|
||||
new ReadOnlyBytes(encoded);
|
||||
var buffer = encoded.ToChunkedReadOnlyBytes(chunkSize);
|
||||
var reader = new BytesReader(buffer);
|
||||
|
||||
var messages = new List<Message>();
|
||||
|
|
|
|||
|
|
@ -14,18 +14,19 @@ namespace Microsoft.AspNetCore.Sockets.Common.Tests.Internal.Formatters
|
|||
public class TextMessageParserTests
|
||||
{
|
||||
[Theory]
|
||||
[InlineData("0:T:;", MessageType.Text, "")]
|
||||
[InlineData("3:T:ABC;", MessageType.Text, "ABC")]
|
||||
[InlineData("11:T:A\nR\rC\r\n;DEF;", MessageType.Text, "A\nR\rC\r\n;DEF")]
|
||||
[InlineData("0:C:;", MessageType.Close, "")]
|
||||
[InlineData("17:C:Connection Closed;", MessageType.Close, "Connection Closed")]
|
||||
[InlineData("0:E:;", MessageType.Error, "")]
|
||||
[InlineData("12:E:Server Error;", MessageType.Error, "Server Error")]
|
||||
public void ReadTextMessage(string encoded, MessageType messageType, string payload)
|
||||
[InlineData(0, "0:T:;", MessageType.Text, "")]
|
||||
[InlineData(0, "3:T:ABC;", MessageType.Text, "ABC")]
|
||||
[InlineData(0, "11:T:A\nR\rC\r\n;DEF;", MessageType.Text, "A\nR\rC\r\n;DEF")]
|
||||
[InlineData(0, "0:C:;", MessageType.Close, "")]
|
||||
[InlineData(0, "17:C:Connection Closed;", MessageType.Close, "Connection Closed")]
|
||||
[InlineData(0, "0:E:;", MessageType.Error, "")]
|
||||
[InlineData(0, "12:E:Server Error;", MessageType.Error, "Server Error")]
|
||||
[InlineData(4, "12:T:Hello, World;", MessageType.Text, "Hello, World")]
|
||||
public void ReadTextMessage(int chunkSize, string encoded, MessageType messageType, string payload)
|
||||
{
|
||||
var parser = new MessageParser();
|
||||
var buffer = Encoding.UTF8.GetBytes(encoded);
|
||||
var reader = new BytesReader(buffer);
|
||||
var reader = new BytesReader(buffer.ToChunkedReadOnlyBytes(chunkSize));
|
||||
|
||||
Assert.True(parser.TryParseMessage(ref reader, MessageFormat.Text, out var message));
|
||||
Assert.Equal(reader.Index, buffer.Length);
|
||||
|
|
|
|||
|
|
@ -12,6 +12,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\Common\ArrayOutput.cs" Link="ArrayOutput.cs" />
|
||||
<Compile Include="..\Common\ByteArrayExtensions.cs" Link="ByteArrayExtensions.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
|||
Loading…
Reference in New Issue