La StopWatch
clase no tiene por qué ser Disposed
o Stopped
por error. Entonces, el código más simple para cronometrar alguna acción es
public partial class With
{
public static long Benchmark(Action action)
{
var stopwatch = Stopwatch.StartNew();
action();
stopwatch.Stop();
return stopwatch.ElapsedMilliseconds;
}
}
Código de llamada de muestra
public void Execute(Action action)
{
var time = With.Benchmark(action);
log.DebugFormat(“Did action in {0} ms.”, time);
}
No me gusta la idea de incluir las iteraciones en el StopWatch
código. Siempre puede crear otro método o extensión que maneje la ejecución de N
iteraciones.
public partial class With
{
public static void Iterations(int n, Action action)
{
for(int count = 0; count < n; count++)
action();
}
}
Código de llamada de muestra
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);
}
Aquí están las versiones del método de extensión
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);
}
}
Y código de llamada de muestra
public void Execute(Action action, int n)
{
var time = action.Iterations(n).Benchmark()
log.DebugFormat(“Did action {0} times in {1} ms.”, n, time);
}
Probé los métodos estáticos y los métodos de extensión (combinando iteraciones y puntos de referencia) y el delta del tiempo de ejecución esperado y el tiempo de ejecución real es <= 1 ms.
Time
se comporta como un método estático, descartando todo el estado existente ensw
, por lo que introducirlo como un método de instancia parece ingenioso.Stopwatch.StartNew
, que es estático por una razón. C # carece de la capacidad de agregar métodos estáticos a las clases existentes (a diferencia de F #), así que entiendo el impulso de hacer esto, pero todavía me deja mal sabor de boca.