diff options
author | Jan Tattermusch <jtattermusch@users.noreply.github.com> | 2017-05-22 13:34:03 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-22 13:34:03 +0200 |
commit | 495cf83c86e04567f8b907a51cc0f86f5068fab6 (patch) | |
tree | 72f761aeff9a1882399e1158b948d8eecf23f833 /src/csharp | |
parent | bce8712f801c47e6711d865d1807b3862158af62 (diff) | |
parent | 19e3d3ba9f1c8e71793e2ad4f648c363d85438f2 (diff) |
Merge pull request #11155 from jtattermusch/csharp_dont_alloc_request
C# qps worker improvements
Diffstat (limited to 'src/csharp')
-rw-r--r-- | src/csharp/Grpc.IntegrationTesting/ClientRunners.cs | 28 | ||||
-rw-r--r-- | src/csharp/Grpc.IntegrationTesting/Histogram.cs | 57 | ||||
-rw-r--r-- | src/csharp/Grpc.IntegrationTesting/HistogramTest.cs | 26 |
3 files changed, 82 insertions, 29 deletions
diff --git a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs index c9f7c42b71..8a44f8d68f 100644 --- a/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs +++ b/src/csharp/Grpc.IntegrationTesting/ClientRunners.cs @@ -140,7 +140,8 @@ namespace Grpc.IntegrationTesting readonly ClientType clientType; readonly RpcType rpcType; readonly PayloadConfig payloadConfig; - readonly Histogram histogram; + readonly Lazy<byte[]> cachedByteBufferRequest; + readonly ThreadLocal<Histogram> threadLocalHistogram; readonly List<Task> runnerTasks; readonly CancellationTokenSource stoppedCts = new CancellationTokenSource(); @@ -155,7 +156,8 @@ namespace Grpc.IntegrationTesting this.clientType = clientType; this.rpcType = rpcType; this.payloadConfig = payloadConfig; - this.histogram = new Histogram(histogramParams.Resolution, histogramParams.MaxPossible); + this.cachedByteBufferRequest = new Lazy<byte[]>(() => new byte[payloadConfig.BytebufParams.ReqSize]); + this.threadLocalHistogram = new ThreadLocal<Histogram>(() => new Histogram(histogramParams.Resolution, histogramParams.MaxPossible), true); this.runnerTasks = new List<Task>(); foreach (var channel in this.channels) @@ -171,7 +173,12 @@ namespace Grpc.IntegrationTesting public ClientStats GetStats(bool reset) { - var histogramData = histogram.GetSnapshot(reset); + var histogramData = new HistogramData(); + foreach (var hist in threadLocalHistogram.Values) + { + hist.GetSnapshot(histogramData, reset); + } + var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds; if (reset) @@ -232,7 +239,7 @@ namespace Grpc.IntegrationTesting stopwatch.Stop(); // spec requires data point in nanoseconds. - histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); + threadLocalHistogram.Value.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); timer.WaitForNext(); } @@ -251,7 +258,7 @@ namespace Grpc.IntegrationTesting stopwatch.Stop(); // spec requires data point in nanoseconds. - histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); + threadLocalHistogram.Value.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); await timer.WaitForNextAsync(); } @@ -273,7 +280,7 @@ namespace Grpc.IntegrationTesting stopwatch.Stop(); // spec requires data point in nanoseconds. - histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); + threadLocalHistogram.Value.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); await timer.WaitForNextAsync(); } @@ -286,7 +293,7 @@ namespace Grpc.IntegrationTesting private async Task RunGenericStreamingAsync(Channel channel, IInterarrivalTimer timer) { - var request = CreateByteBufferRequest(); + var request = cachedByteBufferRequest.Value; var stopwatch = new Stopwatch(); var callDetails = new CallInvocationDetails<byte[], byte[]>(channel, GenericService.StreamingCallMethod, new CallOptions()); @@ -301,7 +308,7 @@ namespace Grpc.IntegrationTesting stopwatch.Stop(); // spec requires data point in nanoseconds. - histogram.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); + threadLocalHistogram.Value.AddObservation(stopwatch.Elapsed.TotalSeconds * SecondsToNanos); await timer.WaitForNextAsync(); } @@ -351,11 +358,6 @@ namespace Grpc.IntegrationTesting }; } - private byte[] CreateByteBufferRequest() - { - return new byte[payloadConfig.BytebufParams.ReqSize]; - } - private static Payload CreateZerosPayload(int size) { return new Payload { Body = ByteString.CopyFrom(new byte[size]) }; diff --git a/src/csharp/Grpc.IntegrationTesting/Histogram.cs b/src/csharp/Grpc.IntegrationTesting/Histogram.cs index 28d1f078a9..9d33c497e6 100644 --- a/src/csharp/Grpc.IntegrationTesting/Histogram.cs +++ b/src/csharp/Grpc.IntegrationTesting/Histogram.cs @@ -84,15 +84,27 @@ namespace Grpc.IntegrationTesting } } - /// <summary> - /// Gets snapshot of stats and reset + /// Gets snapshot of stats and optionally resets the histogram. /// </summary> public HistogramData GetSnapshot(bool reset = false) { lock (myLock) { - return GetSnapshotUnsafe(reset); + var histogramData = new HistogramData(); + GetSnapshotUnsafe(histogramData, reset); + return histogramData; + } + } + + /// <summary> + /// Merges snapshot of stats into <c>mergeTo</c> and optionally resets the histogram. + /// </summary> + public void GetSnapshot(HistogramData mergeTo, bool reset) + { + lock (myLock) + { + GetSnapshotUnsafe(mergeTo, reset); } } @@ -117,24 +129,39 @@ namespace Grpc.IntegrationTesting this.buckets[FindBucket(value)]++; } - private HistogramData GetSnapshotUnsafe(bool reset) + private void GetSnapshotUnsafe(HistogramData mergeTo, bool reset) { - var data = new HistogramData + GrpcPreconditions.CheckArgument(mergeTo.Bucket.Count == 0 || mergeTo.Bucket.Count == buckets.Length); + if (mergeTo.Count == 0) { - Count = count, - Sum = sum, - SumOfSquares = sumOfSquares, - MinSeen = min, - MaxSeen = max, - Bucket = { buckets } - }; + mergeTo.MinSeen = min; + mergeTo.MaxSeen = max; + } + else + { + mergeTo.MinSeen = Math.Min(mergeTo.MinSeen, min); + mergeTo.MaxSeen = Math.Max(mergeTo.MaxSeen, max); + } + mergeTo.Count += count; + mergeTo.Sum += sum; + mergeTo.SumOfSquares += sumOfSquares; - if (reset) + if (mergeTo.Bucket.Count == 0) { - ResetUnsafe(); + mergeTo.Bucket.AddRange(buckets); + } + else + { + for (int i = 0; i < buckets.Length; i++) + { + mergeTo.Bucket[i] += buckets[i]; + } } - return data; + if (reset) + { + ResetUnsafe(); + } } private void ResetUnsafe() diff --git a/src/csharp/Grpc.IntegrationTesting/HistogramTest.cs b/src/csharp/Grpc.IntegrationTesting/HistogramTest.cs index fa160cbd15..e8a2ed0c5b 100644 --- a/src/csharp/Grpc.IntegrationTesting/HistogramTest.cs +++ b/src/csharp/Grpc.IntegrationTesting/HistogramTest.cs @@ -73,7 +73,7 @@ namespace Grpc.IntegrationTesting { var hist = new Histogram(0.01, 60e9); hist.AddObservation(-0.5); // should be in the first bucket - hist.AddObservation(1e12); // should be in the last bucket + hist.AddObservation(1e12); // should be in the last bucket var data = hist.GetSnapshot(); Assert.AreEqual(1, data.Bucket[0]); @@ -81,6 +81,30 @@ namespace Grpc.IntegrationTesting } [Test] + public void MergeSnapshots() + { + var data = new HistogramData(); + + var hist1 = new Histogram(0.01, 60e9); + hist1.AddObservation(-0.5); // should be in the first bucket + hist1.AddObservation(1e12); // should be in the last bucket + hist1.GetSnapshot(data, false); + + var hist2 = new Histogram(0.01, 60e9); + hist2.AddObservation(10000); + hist2.AddObservation(11000); + hist2.GetSnapshot(data, false); + + Assert.AreEqual(4, data.Count); + Assert.AreEqual(-0.5, data.MinSeen); + Assert.AreEqual(1e12, data.MaxSeen); + Assert.AreEqual(1, data.Bucket[0]); + Assert.AreEqual(1, data.Bucket[925]); + Assert.AreEqual(1, data.Bucket[935]); + Assert.AreEqual(1, data.Bucket[data.Bucket.Count - 1]); + } + + [Test] public void Reset() { var hist = new Histogram(0.01, 60e9); |