• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #region Copyright notice and license
2 
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #endregion
18 
19 using System;
20 using System.Threading;
21 using Grpc.Core;
22 using Grpc.Core.Internal;
23 using System.Collections.Generic;
24 using System.Diagnostics;
25 
26 namespace Grpc.Microbenchmarks
27 {
28     public class SendMessageBenchmark
29     {
30         static readonly NativeMethods Native = NativeMethods.Get();
31 
32         GrpcEnvironment environment;
33 
Init()34         public void Init()
35         {
36             Native.grpcsharp_test_override_method("grpcsharp_call_start_batch", "nop");
37             environment = GrpcEnvironment.AddRef();
38         }
39 
Cleanup()40         public void Cleanup()
41         {
42             GrpcEnvironment.ReleaseAsync().Wait();
43             // TODO(jtattermusch): track GC stats
44         }
45 
Run(int threadCount, int iterations, int payloadSize)46         public void Run(int threadCount, int iterations, int payloadSize)
47         {
48             Console.WriteLine(string.Format("SendMessageBenchmark: threads={0}, iterations={1}, payloadSize={2}", threadCount, iterations, payloadSize));
49             var threadedBenchmark = new ThreadedBenchmark(threadCount, () => ThreadBody(iterations, payloadSize));
50             threadedBenchmark.Run();
51         }
52 
ThreadBody(int iterations, int payloadSize)53         private void ThreadBody(int iterations, int payloadSize)
54         {
55             var completionRegistry = new CompletionRegistry(environment, () => environment.BatchContextPool.Lease(), () => throw new NotImplementedException());
56             var cq = CompletionQueueSafeHandle.CreateAsync(completionRegistry);
57             var call = CreateFakeCall(cq);
58 
59             var sendCompletionCallback = new NopSendCompletionCallback();
60             var payload = new byte[payloadSize];
61             var writeFlags = default(WriteFlags);
62 
63             var stopwatch = Stopwatch.StartNew();
64             for (int i = 0; i < iterations; i++)
65             {
66                 call.StartSendMessage(sendCompletionCallback, payload, writeFlags, false);
67                 var callback = completionRegistry.Extract(completionRegistry.LastRegisteredKey);
68                 callback.OnComplete(true);
69             }
70             stopwatch.Stop();
71             Console.WriteLine("Elapsed millis: " + stopwatch.ElapsedMilliseconds);
72 
73             cq.Dispose();
74         }
75 
CreateFakeCall(CompletionQueueSafeHandle cq)76         private static CallSafeHandle CreateFakeCall(CompletionQueueSafeHandle cq)
77         {
78             var call = CallSafeHandle.CreateFake(new IntPtr(0xdead), cq);
79             bool success = false;
80             while (!success)
81             {
82                 // avoid calling destroy on a nonexistent grpc_call pointer
83                 call.DangerousAddRef(ref success);
84             }
85             return call;
86         }
87 
88         private class NopSendCompletionCallback : ISendCompletionCallback
89         {
OnSendCompletion(bool success)90             public void OnSendCompletion(bool success)
91             {
92                 // NOP
93             }
94         }
95     }
96 }
97