Skip to content
This repository was archived by the owner on Dec 18, 2018. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
using System;
using System.Threading.Channels;
using System.Threading.Tasks;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.SignalR.Internal.Protocol;
using Microsoft.AspNetCore.Sockets;
using Microsoft.AspNetCore.Sockets.Internal;

namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
{
[ParameterizedJobConfig(typeof(CoreConfig))]
public class BroadcastBenchmark
{
private DefaultHubLifetimeManager<Hub> _hubLifetimeManager;
private HubContext<Hub> _hubContext;

[Params(1, 10, 1000)]
public int Connections;

[GlobalSetup]
public void GlobalSetup()
{
_hubLifetimeManager = new DefaultHubLifetimeManager<Hub>();
var options = new UnboundedChannelOptions { AllowSynchronousContinuations = true };

for (var i = 0; i < Connections; ++i)
{
var transportToApplication = Channel.CreateUnbounded<byte[]>(options);
var applicationToTransport = Channel.CreateUnbounded<byte[]>(options);

var application = ChannelConnection.Create<byte[]>(input: applicationToTransport, output: transportToApplication);
var transport = ChannelConnection.Create<byte[]>(input: transportToApplication, output: applicationToTransport);
var connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), transport, application);

_hubLifetimeManager.OnConnectedAsync(new HubConnectionContext(Channel.CreateUnbounded<HubMessage>(), connection)).Wait();
}

_hubContext = new HubContext<Hub>(_hubLifetimeManager);
}

[Benchmark]
public Task InvokeAsyncAll()
{
return _hubContext.All.InvokeAsync("Method");
}
}
}
Original file line number Diff line number Diff line change
@@ -1,29 +1,31 @@
using System;
using System.Collections.Generic;
using System.Text;
using BenchmarkDotNet.Columns;
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()
public CoreConfig() : this(Job.Core)
{
// Here because build.cmd calls the other constructor
// and this setting will complain about non-release builds
Add(JitOptimizationsValidator.FailOnError);
}

public CoreConfig(Job job)
{
Add(DefaultConfig.Instance);
Add(MemoryDiagnoser.Default);
Add(StatisticColumn.OperationsPerSecond);

Add(Job.Default
.With(BenchmarkDotNet.Environments.Runtime.Core)
Add(job
.With(RunStrategy.Throughput)
.WithRemoveOutliers(false)
.With(new GcMode() { Server = true })
.With(RunStrategy.Throughput)
.WithLaunchCount(3)
.WithWarmupCount(5)
.WithTargetCount(10));
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
using System;
using BenchmarkDotNet.Attributes;
using Microsoft.AspNetCore.SignalR.Internal;
using Microsoft.AspNetCore.SignalR.Internal.Encoders;
using Microsoft.AspNetCore.SignalR.Internal.Protocol;

namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
{
[ParameterizedJobConfig(typeof(CoreConfig))]
public class HubProtocolBenchmark
{
private HubProtocolReaderWriter _hubProtocolReaderWriter;
private byte[] _binaryInput;
private TestBinder _binder;
private HubMessage _hubMessage;

[Params(Message.NoArguments, Message.FewArguments, Message.ManyArguments, Message.LargeArguments)]
public Message Input { get; set; }

[Params(Protocol.MsgPack, Protocol.Json)]
public Protocol HubProtocol { get; set; }

[GlobalSetup]
public void GlobalSetup()
{
switch (HubProtocol)
{
case Protocol.MsgPack:
_hubProtocolReaderWriter = new HubProtocolReaderWriter(new MessagePackHubProtocol(), new PassThroughEncoder());
break;
case Protocol.Json:
_hubProtocolReaderWriter = new HubProtocolReaderWriter(new JsonHubProtocol(), new PassThroughEncoder());
break;
}

switch (Input)
{
case Message.NoArguments:
_hubMessage = new InvocationMessage("123", true, "Target", null);
break;
case Message.FewArguments:
_hubMessage = new InvocationMessage("123", true, "Target", null, 1, "Foo", 2.0f);
break;
case Message.ManyArguments:
_hubMessage = new InvocationMessage("123", true, "Target", null, 1, "string", 2.0f, true, (byte)9, new byte[] { 5, 4, 3, 2, 1 }, 'c', 123456789101112L);
break;
case Message.LargeArguments:
_hubMessage = new InvocationMessage("123", true, "Target", null, new string('F', 10240), new byte[10240]);
break;
}

_binaryInput = GetBytes(_hubMessage);
_binder = new TestBinder(_hubMessage);
}

[Benchmark]
public void ReadSingleMessage()
{
if (!_hubProtocolReaderWriter.ReadMessages(_binaryInput, _binder, out var _))
{
throw new InvalidOperationException("Failed to read message");
}
}

[Benchmark]
public void WriteSingleMessage()
{
if (_hubProtocolReaderWriter.WriteMessage(_hubMessage).Length != _binaryInput.Length)
{
throw new InvalidOperationException("Failed to write message");
}
}

public enum Protocol
{
MsgPack = 0,
Json = 1
}

public enum Message
{
NoArguments = 0,
FewArguments = 1,
ManyArguments = 2,
LargeArguments = 3
}

private byte[] GetBytes(HubMessage hubMessage)
{
return _hubProtocolReaderWriter.WriteMessage(_hubMessage);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
{
[Config(typeof(CoreConfig))]
[ParameterizedJobConfig(typeof(CoreConfig))]
public class MessageParserBenchmark
{
private static readonly Random Random = new Random();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR.Core\Microsoft.AspNetCore.SignalR.Core.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.SignalR.Common\Microsoft.AspNetCore.SignalR.Common.csproj" />
<ProjectReference Include="..\..\src\Microsoft.AspNetCore.Sockets\Microsoft.AspNetCore.Sockets.csproj" />
<PackageReference Include="BenchmarkDotNet" Version="$(BenchmarkDotNetPackageVersion)" />
<PackageReference Include="Microsoft.AspNetCore.BenchmarkRunner.Sources" Version="$(MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion)" />
<PackageReference Include="System.Threading.Channels" Version="$(SystemThreadingChannelsPackageVersion)" />
</ItemGroup>

</Project>
13 changes: 0 additions & 13 deletions benchmarks/Microsoft.AspNetCore.SignalR.Microbenchmarks/Program.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
// 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.Linq;
using Microsoft.AspNetCore.SignalR.Internal;
using Microsoft.AspNetCore.SignalR.Internal.Protocol;

namespace Microsoft.AspNetCore.SignalR.Microbenchmarks
{
public class TestBinder : IInvocationBinder
{
private readonly Type[] _paramTypes;
private readonly Type _returnType;

public TestBinder(HubMessage expectedMessage)
{
switch (expectedMessage)
{
case StreamInvocationMessage i:
_paramTypes = i.Arguments?.Select(a => a?.GetType() ?? typeof(object))?.ToArray();
break;
case InvocationMessage i:
_paramTypes = i.Arguments?.Select(a => a?.GetType() ?? typeof(object))?.ToArray();
break;
case StreamItemMessage s:
_returnType = s.Item?.GetType() ?? typeof(object);
break;
case CompletionMessage c:
_returnType = c.Result?.GetType() ?? typeof(object);
break;
}
}

public TestBinder() : this(null, null) { }
public TestBinder(Type[] paramTypes) : this(paramTypes, null) { }
public TestBinder(Type returnType) : this(null, returnType) { }
public TestBinder(Type[] paramTypes, Type returnType)
{
_paramTypes = paramTypes;
_returnType = returnType;
}

public Type[] GetParameterTypes(string methodName)
{
if (_paramTypes != null)
{
return _paramTypes;
}
throw new InvalidOperationException("Unexpected binder call");
}

public Type GetReturnType(string invocationId)
{
if (_returnType != null)
{
return _returnType;
}
throw new InvalidOperationException("Unexpected binder call");
}
}
}
1 change: 1 addition & 0 deletions build/dependencies.props
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
</PropertyGroup>
<PropertyGroup Label="Package Versions">
<BenchmarkDotNetPackageVersion>0.10.9</BenchmarkDotNetPackageVersion>
<MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>2.1.0-preview1-27579</MicrosoftAspNetCoreBenchmarkRunnerSourcesPackageVersion>
<BuildBundlerMinifierPackageVersion>2.4.337</BuildBundlerMinifierPackageVersion>
<GoogleProtobufPackageVersion>3.1.0</GoogleProtobufPackageVersion>
<InternalAspNetCoreSdkPackageVersion>2.1.0-preview1-15549</InternalAspNetCoreSdkPackageVersion>
Expand Down
3 changes: 3 additions & 0 deletions build/repo.props
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<Project>
<PropertyGroup>
<EnableBenchmarkValidation>true</EnableBenchmarkValidation>
</PropertyGroup>
<ItemGroup>
<ProjectsToPack Include="$(RepositoryRoot)client-ts\Microsoft.AspNetCore.SignalR.Client.TS\*.csproj" />
</ItemGroup>
Expand Down
2 changes: 1 addition & 1 deletion samples/SocketsSample/wwwroot/hubs.html
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ <h4>Private Message</h4>
connectButton.disabled = true;
disconnectButton.disabled = false;
console.log('http://' + document.location.host + '/' + hubRoute);
connection = new signalR.HubConnection(hubRoute, logger, { transport: transportType, logger: logger });
connection = new signalR.HubConnection(hubRoute, { transport: transportType, logging: logger });
connection.on('Send', function(msg) {
addLine('message-list', msg);
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,13 @@ public override Task InvokeAllAsync(string methodName, object[] args)

private Task InvokeAllWhere(string methodName, object[] args, Func<HubConnectionContext, bool> include)
{
var tasks = new List<Task>(_connections.Count);
var count = _connections.Count;
if (count == 0)
{
return Task.CompletedTask;
}

var tasks = new List<Task>(count);
var message = CreateInvocationMessage(methodName, args);

// TODO: serialize once per format by providing a different stream?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ private static readonly MessagePackHubProtocol _hubProtocol
new object[] { new[] { new StreamInvocationMessage("xyz", "method", null, new[] { new CustomObject(), new CustomObject() }) } },

new object[] { new[] { new CancelInvocationMessage("xyz") } },

new object[] { new[] { PingMessage.Instance } },

new object[]
Expand Down