|
|
|
@ -1,10 +1,8 @@ |
|
|
|
|
using System; |
|
|
|
|
using System.Collections.Generic; |
|
|
|
|
using System.Text; |
|
|
|
|
using BenchmarkDotNet.Attributes; |
|
|
|
|
using Grpc.Core; |
|
|
|
|
using Grpc.Core.Internal; |
|
|
|
|
using Grpc.Core.Internal.Tests; |
|
|
|
|
|
|
|
|
|
namespace Grpc.Microbenchmarks |
|
|
|
|
{ |
|
|
|
@ -12,9 +10,7 @@ namespace Grpc.Microbenchmarks |
|
|
|
|
[MemoryDiagnoser] // allocations |
|
|
|
|
public class Utf8Encode : ISendStatusFromServerCompletionCallback |
|
|
|
|
{ |
|
|
|
|
static readonly NativeMethods Native = NativeMethods.Get(); |
|
|
|
|
|
|
|
|
|
[Params(0, 1, 4, 128, 1024)] |
|
|
|
|
[Params(0)] //, 1, 4, 128, 1024)] |
|
|
|
|
public int PayloadSize { get; set; } |
|
|
|
|
|
|
|
|
|
static readonly Dictionary<int, string> Payloads = new Dictionary<int, string> { |
|
|
|
@ -36,22 +32,50 @@ namespace Grpc.Microbenchmarks |
|
|
|
|
return new string(chars); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private GrpcEnvironment environment; |
|
|
|
|
|
|
|
|
|
[GlobalSetup] |
|
|
|
|
public void Setup() |
|
|
|
|
{ |
|
|
|
|
Native.grpcsharp_test_override_method("grpcsharp_call_start_batch", "nop"); |
|
|
|
|
var native = NativeMethods.Get(); |
|
|
|
|
|
|
|
|
|
// ??? throws ??? |
|
|
|
|
native.grpcsharp_test_override_method(nameof(NativeMethods.grpcsharp_call_send_status_from_server), "nop"); |
|
|
|
|
|
|
|
|
|
environment = GrpcEnvironment.AddRef(); |
|
|
|
|
metadata = MetadataArraySafeHandle.Create(Metadata.Empty); |
|
|
|
|
call = new FakeNativeCall(); |
|
|
|
|
var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException()); |
|
|
|
|
var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry); |
|
|
|
|
call = CreateFakeCall(cq); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static CallSafeHandle CreateFakeCall(CompletionQueueSafeHandle cq) |
|
|
|
|
{ |
|
|
|
|
var call = CallSafeHandle.CreateFake(new IntPtr(0xdead), cq); |
|
|
|
|
bool success = false; |
|
|
|
|
while (!success) |
|
|
|
|
{ |
|
|
|
|
// avoid calling destroy on a nonexistent grpc_call pointer |
|
|
|
|
call.DangerousAddRef(ref success); |
|
|
|
|
} |
|
|
|
|
return call; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
[GlobalCleanup] |
|
|
|
|
public void Cleanup() |
|
|
|
|
{ |
|
|
|
|
metadata.Dispose(); |
|
|
|
|
metadata?.Dispose(); |
|
|
|
|
metadata = null; |
|
|
|
|
call.Dispose(); |
|
|
|
|
call?.Dispose(); |
|
|
|
|
call = null; |
|
|
|
|
|
|
|
|
|
if (environment != null) |
|
|
|
|
{ |
|
|
|
|
environment = null; |
|
|
|
|
GrpcEnvironment.ReleaseAsync().Wait(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
private INativeCall call; |
|
|
|
|
private CallSafeHandle call; |
|
|
|
|
private MetadataArraySafeHandle metadata; |
|
|
|
|
|
|
|
|
|
const int Iterations = 1000; |
|
|
|
@ -62,8 +86,7 @@ namespace Grpc.Microbenchmarks |
|
|
|
|
var status = new Status(StatusCode.OK, payload); |
|
|
|
|
for (int i = 0; i < Iterations; i++) |
|
|
|
|
{ |
|
|
|
|
call.StartSendStatusFromServer(this, status, |
|
|
|
|
metadata, false, null, WriteFlags.NoCompress); |
|
|
|
|
call.StartSendStatusFromServer(this, status, metadata, false, null, WriteFlags.NoCompress); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|