parent
1650d6ab40
commit
34dfa06b4b
1 changed files with 93 additions and 0 deletions
@ -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); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue