forked from grpc/grpc
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
1650d6a
commit 34dfa06
Showing
1 changed file
with
93 additions
and
0 deletions.
There are no files selected for viewing
93 changes: 93 additions & 0 deletions
93
src/csharp/Grpc.Microbenchmarks/UnaryCallOverheadBenchmark.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,93 @@ | ||
#region Copyright notice and license | ||
|
||
// Copyright 2019 The gRPC Authors | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#endregion | ||
|
||
using System.Threading.Tasks; | ||
using BenchmarkDotNet.Attributes; | ||
using Grpc.Core; | ||
using Grpc.Core.Internal; | ||
using System; | ||
|
||
namespace Grpc.Microbenchmarks | ||
{ | ||
// this test creates a real server and client, measuring the inherent inbuilt | ||
// platform overheads; the marshallers **DO NOT ALLOCATE**, so any allocations | ||
// are from the framework, not the messages themselves | ||
|
||
// important: allocs are not reliable on .NET Core until .NET Core 3, since | ||
// this test involves multiple threads | ||
|
||
[ClrJob, CoreJob] // test .NET Core and .NET Framework | ||
[MemoryDiagnoser] // allocations | ||
public class UnaryCallOverheadBenchmark | ||
{ | ||
private static readonly Task<string> CompletedString = Task.FromResult(""); | ||
private static readonly byte[] EmptyBlob = new byte[0]; | ||
private static readonly Marshaller<string> EmptyMarshaller = new Marshaller<string>(_ => EmptyBlob, _ => ""); | ||
private static readonly Method<string, string> PingMethod = new Method<string, string>(MethodType.Unary, nameof(PingBenchmark), "Ping", EmptyMarshaller, EmptyMarshaller); | ||
|
||
[Benchmark] | ||
public string Ping() | ||
{ | ||
return client.Ping("", new CallOptions()); | ||
} | ||
|
||
Channel channel; | ||
PingClient client; | ||
|
||
[GlobalSetup] | ||
public void Setup() | ||
{ | ||
// create client | ||
channel = new Channel("localhost", 10042, ChannelCredentials.Insecure); | ||
client = new PingClient(new DefaultCallInvoker(channel)); | ||
|
||
var native = NativeMethods.Get(); | ||
|
||
// replace the implementation of a native method with a fake | ||
NativeMethods.Delegates.grpcsharp_call_start_unary_delegate fakeCallStartUnary = (CallSafeHandle call, BatchContextSafeHandle ctx, byte[] sendBuffer, UIntPtr sendBufferLen, WriteFlags writeFlags, MetadataArraySafeHandle metadataArray, CallFlags metadataFlags) => { | ||
return native.grpcsharp_test_call_start_unary_echo(call, ctx, sendBuffer, sendBufferLen, writeFlags, metadataArray, metadataFlags); | ||
}; | ||
native.GetType().GetField(nameof(native.grpcsharp_call_start_unary)).SetValue(native, fakeCallStartUnary); | ||
|
||
NativeMethods.Delegates.grpcsharp_completion_queue_pluck_delegate fakeCqPluck = (CompletionQueueSafeHandle cq, IntPtr tag) => { | ||
return new CompletionQueueEvent { | ||
type = CompletionQueueEvent.CompletionType.OpComplete, | ||
success = 1, | ||
tag = tag | ||
}; | ||
}; | ||
native.GetType().GetField(nameof(native.grpcsharp_completion_queue_pluck)).SetValue(native, fakeCqPluck); | ||
} | ||
|
||
[GlobalCleanup] | ||
public async Task Cleanup() | ||
{ | ||
await channel.ShutdownAsync(); | ||
} | ||
|
||
class PingClient : LiteClientBase | ||
{ | ||
public PingClient(CallInvoker callInvoker) : base(callInvoker) { } | ||
|
||
public string Ping(string request, CallOptions options) | ||
{ | ||
return CallInvoker.BlockingUnaryCall(PingMethod, null, options, request); | ||
} | ||
} | ||
} | ||
} |