PingBenchmark.cs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. #region Copyright notice and license
  2. // Copyright 2019 The 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.Threading.Tasks;
  17. using BenchmarkDotNet.Attributes;
  18. using Grpc.Core;
  19. namespace Grpc.Microbenchmarks
  20. {
  21. // this test creates a real server and client, measuring the inherent inbuilt
  22. // platform overheads; the marshallers **DO NOT ALLOCATE**, so any allocations
  23. // are from the framework, not the messages themselves
  24. // important: allocs are not reliable on .NET Core until .NET Core 3, since
  25. // this test involves multiple threads
  26. [ClrJob, CoreJob] // test .NET Core and .NET Framework
  27. [MemoryDiagnoser] // allocations
  28. public class PingBenchmark
  29. {
  30. private static readonly Task<string> CompletedString = Task.FromResult("");
  31. private static readonly byte[] EmptyBlob = new byte[0];
  32. private static readonly Marshaller<string> EmptyMarshaller = new Marshaller<string>(_ => EmptyBlob, _ => "");
  33. private static readonly Method<string, string> PingMethod = new Method<string, string>(MethodType.Unary, nameof(PingBenchmark), "Ping", EmptyMarshaller, EmptyMarshaller);
  34. [Benchmark]
  35. public async ValueTask<string> PingAsync()
  36. {
  37. using (var result = client.PingAsync("", new CallOptions()))
  38. {
  39. return await result.ResponseAsync;
  40. }
  41. }
  42. [Benchmark]
  43. public string Ping()
  44. {
  45. return client.Ping("", new CallOptions());
  46. }
  47. private Task<string> ServerMethod(string request, ServerCallContext context)
  48. {
  49. return CompletedString;
  50. }
  51. Server server;
  52. Channel channel;
  53. PingClient client;
  54. [GlobalSetup]
  55. public async Task Setup()
  56. {
  57. // create server
  58. server = new Server {
  59. Ports = { new ServerPort("localhost", 10042, ServerCredentials.Insecure) },
  60. Services = { ServerServiceDefinition.CreateBuilder().AddMethod(PingMethod, ServerMethod).Build() },
  61. };
  62. server.Start();
  63. // create client
  64. channel = new Channel("localhost", 10042, ChannelCredentials.Insecure);
  65. await channel.ConnectAsync();
  66. client = new PingClient(new DefaultCallInvoker(channel));
  67. }
  68. [GlobalCleanup]
  69. public async Task Cleanup()
  70. {
  71. await channel.ShutdownAsync();
  72. await server.ShutdownAsync();
  73. }
  74. class PingClient : ClientBase
  75. {
  76. public PingClient(CallInvoker callInvoker) : base(callInvoker) { }
  77. public AsyncUnaryCall<string> PingAsync(string request, CallOptions options)
  78. {
  79. return CallInvoker.AsyncUnaryCall(PingMethod, null, options, request);
  80. }
  81. public string Ping(string request, CallOptions options)
  82. {
  83. return CallInvoker.BlockingUnaryCall(PingMethod, null, options, request);
  84. }
  85. }
  86. }
  87. }