StopWatch
类在发生错误时不需要被 Disposed
或 Stopped
。因此,测量某个操作所需的最简代码为:
public partial class With
{
public static long Benchmark(Action action)
{
var stopwatch = Stopwatch.StartNew();
action();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
}
示例调用代码
public void Execute(Action action)
{
var time = With.Benchmark(action);
log.DebugFormat(“Did action in {0} ms.”, time);
}
我不喜欢将迭代包含在StopWatch
代码中的想法。您可以始终创建另一个处理执行N
次迭代的方法或扩展。
public partial class With
{
public static void Iterations(int n, Action action)
{
for(int count = 0; count < n; count++)
action();
}
}
示例调用代码
public void Execute(Action action, int n)
{
var time = With.Benchmark(With.Iterations(n, action));
log.DebugFormat(“Did action {0} times in {1} ms.”, n, time);
}
以下是扩展方法版本。
public static class Extensions
{
public static long Benchmark(this Action action)
{
return With.Benchmark(action);
}
public static Action Iterations(this Action action, int n)
{
return () => With.Iterations(n, action);
}
}
同时附上调用示例代码
public void Execute(Action action, int n)
{
var time = action.Iterations(n).Benchmark()
log.DebugFormat(“Did action {0} times in {1} ms.”, n, time);
}
我测试了静态方法和扩展方法(结合迭代和基准测试),预期执行时间与实际执行时间的差值小于等于1毫秒。
Time
表现为静态方法,丢弃sw
中所有现有状态,因此将其引入为实例方法只是看起来花哨。 - ildjarnStopwatch.StartNew
更像是一个实例方法,后者之所以是静态的是有原因的。C#缺乏向现有类添加静态方法的能力(不像F#),因此我理解这种做法的冲动,但它仍然让我感到不舒服。 - ildjarn