diff --git a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj index 899e41ce532..f775e4c85fb 100644 --- a/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj +++ b/src/csharp/Grpc.Microbenchmarks/Grpc.Microbenchmarks.csproj @@ -6,6 +6,7 @@ net461;netcoreapp2.1 Exe true + true diff --git a/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs new file mode 100644 index 00000000000..1c3f4d261ee --- /dev/null +++ b/src/csharp/Grpc.Microbenchmarks/Utf8Decode.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Text; +using BenchmarkDotNet.Attributes; +using Grpc.Core.Internal; + +namespace Grpc.Microbenchmarks +{ + [ClrJob, CoreJob] // test .NET Core and .NET Framework + [MemoryDiagnoser] // allocations + public class Utf8Decode + { + [Params(0, 1, 4, 128, 1024)] + public int PayloadSize { get; set; } + + static readonly Dictionary Payloads = new Dictionary { + { 0, Invent(0) }, + { 1, Invent(1) }, + { 4, Invent(4) }, + { 128, Invent(128) }, + { 1024, Invent(1024) }, + }; + + static byte[] Invent(int length) + { + var rand = new Random(Seed: length); + var chars = new char[length]; + for(int i = 0; i < chars.Length; i++) + { + chars[i] = (char)rand.Next(32, 300); + } + return Encoding.UTF8.GetBytes(chars); + } + + const int Iterations = 1000; + [Benchmark(OperationsPerInvoke = Iterations)] + public unsafe void Run() + { + byte[] payload = Payloads[PayloadSize]; + fixed (byte* ptr = payload) + { + var iPtr = new IntPtr(ptr); + for (int i = 0; i < Iterations; i++) + { + MarshalUtils.PtrToStringUTF8(iPtr, payload.Length); + } + } + } + } +}