¿Es DateTime.Now la mejor manera de medir el rendimiento de una función? [cerrado]

Resuelto David Basarab asked hace 16 años • 16 respuestas

Necesito encontrar un cuello de botella y necesito medir el tiempo con la mayor precisión posible.

¿Es el siguiente fragmento de código la mejor manera de medir el rendimiento?

DateTime startTime = DateTime.Now;

// Some execution process

DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
David Basarab avatar Aug 27 '08 00:08 David Basarab
Aceptado

No, no es. Utilice el cronómetro (en System.Diagnostics)

Stopwatch sw = Stopwatch.StartNew();
PerformWork();
sw.Stop();

Console.WriteLine("Time taken: {0}ms", sw.Elapsed.TotalMilliseconds);

El cronómetro comprueba automáticamente la existencia de temporizadores de alta precisión.

Vale la pena mencionar que DateTime.Nowa menudo es un poco más lento DateTime.UtcNowdebido al trabajo que hay que hacer con las zonas horarias, el horario de verano y demás.

DateTime.UtcNow normalmente tiene una resolución de 15 ms. Consulte la publicación del blog de John Chapman sobre DateTime.Nowprecisión para obtener un excelente resumen.

Trivia interesante: el cronómetro vuelve a funcionar DateTime.UtcNowsi su hardware no admite un contador de alta frecuencia. Puede comprobar si Stopwatch utiliza hardware para lograr una alta precisión observando el campo estático Stopwatch.IsHighResolution .

Markus Olsson avatar Aug 26 '2008 17:08 Markus Olsson

Si quieres algo rápido y sucio, te sugiero que utilices el cronómetro para obtener un mayor grado de precisión.

Stopwatch sw = new Stopwatch();
sw.Start();
// Do Work
sw.Stop();

Console.WriteLine("Elapsed time: {0}", sw.Elapsed.TotalMilliseconds);

Alternativamente, si necesita algo un poco más sofisticado, probablemente debería considerar el uso de un generador de perfiles de terceros como ANTS .

mmcdole avatar Aug 26 '2008 17:08 mmcdole

Este artículo dice que, en primer lugar , debe comparar tres alternativas Stopwatch, DateTime.NowY.DateTime.UtcNow

También muestra que en algunos casos (cuando el contador de rendimiento no existe) Stopwatch usa DateTime.UtcNow + algún procesamiento adicional. Por eso es obvio que en ese caso DateTime.UtcNow es la mejor opción (porque otros lo usan + algo de procesamiento)

Sin embargo, resulta que el contador casi siempre existe; consulte la Explicación sobre el contador de rendimiento de alta resolución y su existencia en relación con .NET Stopwatch. .

A continuación se muestra un gráfico de rendimiento. Observe el bajo costo de rendimiento que tiene UtcNow en comparación con las alternativas:

Ingrese la descripción de la imagen aquí

El eje X es el tamaño de los datos de la muestra y el eje Y es el tiempo relativo del ejemplo.

Una cosa Stopwatchque es mejor es que proporciona mediciones de tiempo de mayor resolución. Otra es su naturaleza más OO. Sin embargo, crear un contenedor OO UtcNowno puede ser difícil.

Valentin Kuzub avatar Aug 08 '2011 18:08 Valentin Kuzub

Es útil insertar su código de evaluación comparativa en una clase/método de utilidad. StopWatchNo es necesario que la clase Disposedtenga Stoppedun 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);
}

Aquí está la versión del método de extensión.

public static class Extensions
{
    public static long Benchmark(this Action action)
    {
        return With.Benchmark(action);
    }
}

Y código de llamada de muestra

public void Execute(Action action)
{
    var time = action.Benchmark()
    log.DebugFormat(“Did action in {0} ms.”, time);
}
Anthony Mastrean avatar Sep 02 '2008 15:09 Anthony Mastrean