C# benchmarks provide userTime and systemTime info

pull/13568/head
Jan Tattermusch 7 years ago
parent ba89ad4065
commit 3267108e52
  1. 13
      src/csharp/Grpc.IntegrationTesting/ClientRunners.cs
  2. 13
      src/csharp/Grpc.IntegrationTesting/ServerRunners.cs
  3. 6
      src/csharp/Grpc.IntegrationTesting/StressTestClient.cs
  4. 90
      src/csharp/Grpc.IntegrationTesting/TimeStats.cs
  5. 63
      src/csharp/Grpc.IntegrationTesting/WallClockStopwatch.cs

@ -131,7 +131,7 @@ namespace Grpc.IntegrationTesting
readonly List<Task> runnerTasks;
readonly CancellationTokenSource stoppedCts = new CancellationTokenSource();
readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
readonly TimeStats timeStats = new TimeStats();
readonly AtomicCounter statsResetCount = new AtomicCounter();
public ClientRunnerImpl(List<Channel> channels, ClientType clientType, RpcType rpcType, int outstandingRpcsPerChannel, LoadParams loadParams, PayloadConfig payloadConfig, HistogramParams histogramParams, Func<BasicProfiler> profilerFactory)
@ -165,7 +165,7 @@ namespace Grpc.IntegrationTesting
hist.GetSnapshot(histogramData, reset);
}
var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds;
var timeSnapshot = timeStats.GetSnapshot(reset);
if (reset)
{
@ -173,15 +173,14 @@ namespace Grpc.IntegrationTesting
}
GrpcEnvironment.Logger.Info("[ClientRunnerImpl.GetStats] GC collection counts: gen0 {0}, gen1 {1}, gen2 {2}, (histogram reset count:{3}, seconds since reset: {4})",
GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), statsResetCount.Count, secondsElapsed);
GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), statsResetCount.Count, timeSnapshot.WallClockTime.TotalSeconds);
// TODO: populate user time and system time
return new ClientStats
{
Latencies = histogramData,
TimeElapsed = secondsElapsed,
TimeUser = 0,
TimeSystem = 0
TimeElapsed = timeSnapshot.WallClockTime.TotalSeconds,
TimeUser = timeSnapshot.UserProcessorTime.TotalSeconds,
TimeSystem = timeSnapshot.PrivilegedProcessorTime.TotalSeconds
};
}

@ -117,7 +117,7 @@ namespace Grpc.IntegrationTesting
public class ServerRunnerImpl : IServerRunner
{
readonly Server server;
readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
readonly TimeStats timeStats = new TimeStats();
public ServerRunnerImpl(Server server)
{
@ -138,17 +138,16 @@ namespace Grpc.IntegrationTesting
/// <returns>The stats.</returns>
public ServerStats GetStats(bool reset)
{
var secondsElapsed = wallClockStopwatch.GetElapsedSnapshot(reset).TotalSeconds;
var timeSnapshot = timeStats.GetSnapshot(reset);
GrpcEnvironment.Logger.Info("[ServerRunner.GetStats] GC collection counts: gen0 {0}, gen1 {1}, gen2 {2}, (seconds since last reset {3})",
GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), secondsElapsed);
GC.CollectionCount(0), GC.CollectionCount(1), GC.CollectionCount(2), timeSnapshot.WallClockTime.TotalSeconds);
// TODO: populate user time and system time
return new ServerStats
{
TimeElapsed = secondsElapsed,
TimeUser = 0,
TimeSystem = 0
TimeElapsed = timeSnapshot.WallClockTime.TotalSeconds,
TimeUser = timeSnapshot.UserProcessorTime.TotalSeconds,
TimeSystem = timeSnapshot.PrivilegedProcessorTime.TotalSeconds
};
}

@ -243,7 +243,7 @@ namespace Grpc.IntegrationTesting
const string GaugeName = "csharp_overall_qps";
readonly Histogram histogram;
readonly WallClockStopwatch wallClockStopwatch = new WallClockStopwatch();
readonly TimeStats timeStats = new TimeStats();
public MetricsServiceImpl(Histogram histogram)
{
@ -280,9 +280,9 @@ namespace Grpc.IntegrationTesting
long GetQpsAndReset()
{
var snapshot = histogram.GetSnapshot(true);
var elapsedSnapshot = wallClockStopwatch.GetElapsedSnapshot(true);
var timeSnapshot = timeStats.GetSnapshot(true);
return (long) (snapshot.Count / elapsedSnapshot.TotalSeconds);
return (long) (snapshot.Count / timeSnapshot.WallClockTime.TotalSeconds);
}
}
}

@ -0,0 +1,90 @@
#region Copyright notice and license
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Google.Protobuf;
using Grpc.Core;
using Grpc.Core.Utils;
using NUnit.Framework;
using Grpc.Testing;
namespace Grpc.IntegrationTesting
{
/// <summary>
/// Snapshottable time statistics.
/// </summary>
public class TimeStats
{
readonly object myLock = new object();
DateTime lastWallClock;
TimeSpan lastUserTime;
TimeSpan lastPrivilegedTime;
public TimeStats()
{
lastWallClock = DateTime.UtcNow;
lastUserTime = Process.GetCurrentProcess().UserProcessorTime;
lastPrivilegedTime = Process.GetCurrentProcess().PrivilegedProcessorTime;
}
public Snapshot GetSnapshot(bool reset)
{
lock (myLock)
{
var wallClock = DateTime.UtcNow;
var userTime = Process.GetCurrentProcess().UserProcessorTime;
var privilegedTime = Process.GetCurrentProcess().PrivilegedProcessorTime;
var snapshot = new Snapshot(wallClock - lastWallClock, userTime - lastUserTime, privilegedTime - lastPrivilegedTime);
if (reset)
{
lastWallClock = wallClock;
lastUserTime = userTime;
lastPrivilegedTime = privilegedTime;
}
return snapshot;
}
}
public class Snapshot
{
public TimeSpan WallClockTime { get; }
public TimeSpan UserProcessorTime { get; }
public TimeSpan PrivilegedProcessorTime { get; }
public Snapshot(TimeSpan wallClockTime, TimeSpan userProcessorTime, TimeSpan privilegedProcessorTime)
{
this.WallClockTime = wallClockTime;
this.UserProcessorTime = userProcessorTime;
this.PrivilegedProcessorTime = privilegedProcessorTime;
}
public override string ToString()
{
return string.Format("[TimeStats.Snapshot: wallClock {0}, userProcessor {1}, privilegedProcessor {2}]", WallClockTime, UserProcessorTime, PrivilegedProcessorTime);
}
}
}
}

@ -1,63 +0,0 @@
#region Copyright notice and license
// Copyright 2015 gRPC authors.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using Google.Protobuf;
using Grpc.Core;
using Grpc.Core.Utils;
using NUnit.Framework;
using Grpc.Testing;
namespace Grpc.IntegrationTesting
{
/// <summary>
/// Snapshottable wall clock stopwatch.
/// </summary>
public class WallClockStopwatch
{
long startTicks;
public WallClockStopwatch()
{
this.startTicks = DateTime.UtcNow.Ticks;
}
public TimeSpan GetElapsedSnapshot(bool reset)
{
var utcNow = DateTime.UtcNow;
long oldStartTicks;
if (reset)
{
oldStartTicks = Interlocked.Exchange(ref this.startTicks, utcNow.Ticks);
}
else
{
oldStartTicks = this.startTicks;
}
return utcNow - new DateTime(oldStartTicks, DateTimeKind.Utc);
}
}
}
Loading…
Cancel
Save