added benchmarking suite

This commit is contained in:
Christian Köllner 2020-02-08 18:36:21 +01:00
parent bb1a8bf51c
commit 3a429462e6
18 changed files with 392 additions and 0 deletions

View File

@ -0,0 +1,24 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
<PackageReference Include="Capnp.Net.Runtime" Version="1.2.189" />
<PackageReference Include="CapnpC.CSharp.MsBuild.Generation" Version="1.2.138" />
<PackageReference Include="Google.Protobuf" Version="3.11.3" />
<PackageReference Include="Grpc.Net.Client" Version="2.27.0" />
<PackageReference Include="Grpc.Tools" Version="2.27.0">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference>
</ItemGroup>
<ItemGroup>
<Protobuf Include="Protos\Echo.proto" GrpcServices="Client" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,46 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using Capnp.Rpc;
using CapnpGen;
using System;
using System.Collections.Generic;
using System.Text;
namespace Benchmark
{
public class CapnpBenchmark
{
[Params(20, 200, 2000, 20000, 200000, 2000000)]
public int PayloadBytes;
TcpRpcClient _client;
IEchoer _echoer;
byte[] _payload;
[GlobalSetup]
public void Setup()
{
_client = new TcpRpcClient("localhost", 5002);
_client.WhenConnected.Wait();
_echoer = _client.GetMain<IEchoer>();
_payload = new byte[PayloadBytes];
new Random().NextBytes(_payload);
}
[GlobalCleanup]
public void Cleanup()
{
_echoer.Dispose();
_client.Dispose();
}
[Benchmark]
public void Echo()
{
var t = _echoer.Echo(_payload);
t.Wait();
if (t.Result?.Count != _payload.Length)
throw new InvalidOperationException("Echo server malfunction");
}
}
}

View File

@ -0,0 +1,42 @@
using BenchmarkDotNet.Attributes;
using BenchmarkDotNet.Jobs;
using Grpc.Net.Client;
using System;
using System.Collections.Generic;
using System.Text;
namespace Benchmark
{
public class GrpcBenchmark
{
[Params(20, 200, 2000, 20000, 200000, 2000000)]
public int PayloadBytes;
GrpcChannel _channel;
Echoer.EchoerClient _echoer;
byte[] _payload;
[GlobalSetup]
public void Setup()
{
_channel = GrpcChannel.ForAddress("https://localhost:5001");
_echoer = new Echoer.EchoerClient(_channel);
_payload = new byte[PayloadBytes];
new Random().NextBytes(_payload);
}
[GlobalCleanup]
public void Teardown()
{
_channel.Dispose();
}
[Benchmark]
public void Echo()
{
var reply = _echoer.Echo(new EchoRequest { Payload = Google.Protobuf.ByteString.CopyFrom(_payload) });
if (reply?.Payload?.Length != _payload.Length)
throw new InvalidOperationException("Echo server malfunction");
}
}
}

View File

@ -0,0 +1,18 @@
using BenchmarkDotNet.Running;
using Capnp.Rpc;
using Grpc.Net.Client;
using System;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Benchmark
{
class Program
{
static void Main(string[] args)
{
BenchmarkRunner.Run<GrpcBenchmark>();
BenchmarkRunner.Run<CapnpBenchmark>();
}
}
}

View File

@ -0,0 +1,5 @@
@0x8c309c720de8cf7c;
interface Echoer {
echo @0 (input : Data) -> (output : Data);
}

View File

@ -0,0 +1,13 @@
syntax = "proto3";
service Echoer {
rpc Echo (EchoRequest) returns (EchoReply);
}
message EchoRequest {
bytes payload = 1;
}
message EchoReply {
bytes payload = 1;
}

View File

@ -0,0 +1,37 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.29728.190
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EchoServiceGrpc", "EchoServiceGrpc\EchoServiceGrpc.csproj", "{D59C7B71-3887-426B-A636-2DBDA0549817}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Benchmark", "Benchmark\Benchmark.csproj", "{7F7580CA-CCF0-4650-87BF-502D51A8F435}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EchoServiceCapnp", "EchoServiceCapnp\EchoServiceCapnp.csproj", "{309A4A26-F29E-4F49-AB49-76BAE0FD7D62}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{D59C7B71-3887-426B-A636-2DBDA0549817}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D59C7B71-3887-426B-A636-2DBDA0549817}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D59C7B71-3887-426B-A636-2DBDA0549817}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D59C7B71-3887-426B-A636-2DBDA0549817}.Release|Any CPU.Build.0 = Release|Any CPU
{7F7580CA-CCF0-4650-87BF-502D51A8F435}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7F7580CA-CCF0-4650-87BF-502D51A8F435}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7F7580CA-CCF0-4650-87BF-502D51A8F435}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7F7580CA-CCF0-4650-87BF-502D51A8F435}.Release|Any CPU.Build.0 = Release|Any CPU
{309A4A26-F29E-4F49-AB49-76BAE0FD7D62}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{309A4A26-F29E-4F49-AB49-76BAE0FD7D62}.Debug|Any CPU.Build.0 = Debug|Any CPU
{309A4A26-F29E-4F49-AB49-76BAE0FD7D62}.Release|Any CPU.ActiveCfg = Release|Any CPU
{309A4A26-F29E-4F49-AB49-76BAE0FD7D62}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {A6702BC8-8CC0-4BDA-8BD5-D5D268291E93}
EndGlobalSection
EndGlobal

View File

@ -0,0 +1,13 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Capnp.Net.Runtime" Version="1.2.189" />
<PackageReference Include="CapnpC.CSharp.MsBuild.Generation" Version="1.2.138" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,20 @@
using Capnp.Rpc;
using EchoServiceCapnp.Services;
using System;
using System.Net;
namespace EchoServiceCapnp
{
class Program
{
static void Main(string[] args)
{
using (var server = new TcpRpcServer(IPAddress.Any, 5002))
{
server.Main = new CapnpEchoService();
Console.WriteLine("Press RETURN to stop listening");
Console.ReadLine();
}
}
}
}

View File

@ -0,0 +1,5 @@
@0x8c309c720de8cf7c;
interface Echoer {
echo @0 (input : Data) -> (output : Data);
}

View File

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace EchoServiceCapnp.Services
{
public class CapnpEchoService : CapnpGen.IEchoer
{
public void Dispose()
{
}
public Task<IReadOnlyList<byte>> Echo(IReadOnlyList<byte> input, CancellationToken cancellationToken_ = default)
{
return Task.FromResult(input);
}
}
}

View File

@ -0,0 +1,15 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>
<ItemGroup>
<Protobuf Include="Protos\Echo.proto" GrpcServices="Server" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Grpc.AspNetCore" Version="2.24.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Hosting;
namespace EchoService
{
public class Program
{
public static void Main(string[] args)
{
CreateHostBuilder(args).Build().Run();
}
// Additional configuration is required to successfully run gRPC on macOS.
// For instructions on how to configure Kestrel and gRPC clients on macOS, visit https://go.microsoft.com/fwlink/?linkid=2099682
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
});
}
}

View File

@ -0,0 +1,13 @@
syntax = "proto3";
service Echoer {
rpc Echo (EchoRequest) returns (EchoReply);
}
message EchoRequest {
bytes payload = 1;
}
message EchoReply {
bytes payload = 1;
}

View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Grpc.Core;
using Microsoft.Extensions.Logging;
namespace EchoService
{
public class GrpcEchoService : Echoer.EchoerBase
{
private readonly ILogger<GrpcEchoService> _logger;
public GrpcEchoService(ILogger<GrpcEchoService> logger)
{
_logger = logger;
}
public override Task<EchoReply> Echo(EchoRequest request, ServerCallContext context)
{
return Task.FromResult(new EchoReply
{
Payload = request.Payload
});
}
}
}

View File

@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
namespace EchoService
{
public class Startup
{
// This method gets called by the runtime. Use this method to add services to the container.
// For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
public void ConfigureServices(IServiceCollection services)
{
services.AddGrpc();
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapGrpcService<GrpcEchoService>();
endpoints.MapGet("/", async context =>
{
await context.Response.WriteAsync("Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909");
});
});
}
}
}

View File

@ -0,0 +1,10 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"System": "Warning",
"Grpc": "Warning",
"Microsoft": "Warning"
}
}
}

View File

@ -0,0 +1,15 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Warning"
}
},
"AllowedHosts": "*",
"Kestrel": {
"EndpointDefaults": {
"Protocols": "Http2"
}
}
}