SendMessageBenchmark.cs 3.2 KB

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