The StopWatch class does not need to be Disposed or Stopped on error. So, the simplest code to time some action is
public partial class With { public static long Benchmark(Action action) { var stopwatch = Stopwatch.StartNew(); action(); stopwatch.Stop(); return stopwatch.ElapsedMilliseconds; } }
Sample calling code
public void Execute(Action action) { var time = With.Benchmark(action); log.DebugFormat(“Did action in {0} ms.”, time); }
I don't like the idea of including the iterations into the StopWatch code. You can always create another method or extension that handles executing N iterations.
public partial class With { public static void Iterations(int n, Action action) { for(int count = 0; count < n; count++) action(); } }
Sample calling code
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); }
Here are the extension method versions
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); } }
And sample calling code
public void Execute(Action action, int n) { var time = action.Iterations(n).Benchmark() log.DebugFormat(“Did action {0} times in {1} ms.”, n, time); }
I tested the static methods and extension methods (combining iterations and benchmark) and the delta of expected execution time and real execution time is <= 1 ms.