Pregunta

Quiero medir la ejecución de una pieza de código y me pregunto cuál es el mejor método para hacer esto es?

Opción 1:

DateTime StartTime = DateTime.Now;

//Code

TimeSpan ts = DateTime.Now.Subtract(StartTime);
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");

Opción 2:         usando System.Diagnostics;

    Stopwatch stopWatch = new Stopwatch();
    stopWatch.Start();

    //Code

    stopWatch.Stop();
    // Get the elapsed time as a TimeSpan value.
    TimeSpan ts = stopWatch.Elapsed;

    // Format and display the TimeSpan value.
    string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
    Console.WriteLine(elapsedTime, "RunTime");

Esto no es simplemente para la evaluación comparativa, es en realidad parte de la aplicación. El tiempo de la función tarda en ejecutar son datos relevantes. Sin embargo, no tiene por qué ser atómica o hiper-precisa.

¿Qué opción es mejor para el código de producción, o hace cualquier otro uso algo diferente y tal vez mejor?

¿Fue útil?

Solución

La clase Stopwatch está diseñado específicamente para medir el tiempo transcurrido y puede (si está disponible en su hardware) proporcionar una buena granularidad / exactitud utilizando un temporizador de hardware de alta frecuencia subyacente. Así que esto parece la mejor opción.

El IsHighResolution propiedad se puede utilizar para determinar si la alta resolución de tiempo está disponible. Por la documentación, que ofrece esta clase un envoltorio en la 'mejor disponible' API de Win32 para la sincronización exacta:

  

Específicamente, el campo Frequency y   método GetTimestamp se puede utilizar en   lugar de la API de Win32 no administrado   QueryPerformanceFrequency y   QueryPerformanceCounter.

Hay antecedentes detallados sobre los API de Win32 [aquí] y en la documentación de MSDN vinculados 2 .

  

de alta resolución del temporizador

     

Un contador es un término general utilizado en   programación para referirse a una   aumentando la variable. algunos sistemas   incluir un rendimiento de alta resolución   contador que proporciona alta resolución   transcurridos veces.

     

Si un rendimiento de alta resolución   contador existe en el sistema, puede   utilizar el QueryPerformanceFrequency   funcionar para expresar la frecuencia, en   recuentos por segundo. El valor de la   recuento depende del procesador. En algunos   procesadores, por ejemplo, el recuento   podría ser la velocidad del ciclo de la   reloj del procesador.

     

El QueryPerformanceCounter función   recupera el valor actual de la   de alta resolución de contador de rendimiento.   Al llamar a esta función en el   principio y final de una sección de   código, una aplicación utiliza esencialmente   el contador como una alta resolución   Temporizador. Por ejemplo, supongamos que    QueryPerformanceFrequency indica   que la frecuencia de la   contador de rendimiento de alta resolución está   50.000 recuentos por segundo. Si el   las llamadas de solicitud    QueryPerformanceCounter inmediatamente   antes e inmediatamente después de la   sección de código a ser programado, el   valores de contador pueden ser 1500 recuentos   y 3500 recuentos, respectivamente. Estas   indicarían que los valores .04 segundos   (2000 unidades) transcurrido mientras que el código   ejecutado.

Otros consejos

No se trata sólo de que StopWatch es más preciso, pero también que DateTime.Now dará resultados incorrectos en algunas circunstancias.

Tenga en cuenta lo que ocurre durante un horario de verano de conmutación, por ejemplo - el uso de DateTime.Now realmente puede dar un negativa Respuesta

Me suelen utilizar StopWatch para este tipo de situación.

A partir de la página MSDN :

  

Cronómetro

     

Proporciona un conjunto de métodos y   propiedades que se pueden utilizar para   medir con precisión el tiempo transcurrido.

En el siguiente post lo uso para comparar el tiempo de ejecución de LINQ vs PLINQ:

Parallel LINQ (PLINQ) con Visual Studio 2010

Ni perjudicará el rendimiento, ya que se dice que no es tan crítica. Cronómetro parece más apropiado - sólo está restando tiempo al tiempo y no uno de fecha de otro. Fecha asunto lleva un poco más de memoria y CPU vez de tratar. También hay maneras de hacer el código más limpio, en caso de que planea volver a utilizarlo en varios lugares. La sobrecarga using viene a la mente. Voy a buscar un ejemplo. Ok, código robado de:

http://stevesmithblog.com/blog/great : utiliza-de-usando-declaración-en-c /

public class ConsoleAutoStopWatch : IDisposable
{
    private readonly Stopwatch _stopWatch;

    public ConsoleAutoStopWatch()
    {
        _stopWatch = new Stopwatch();
        _stopWatch.Start();
    }

    public void Dispose()
    {
        _stopWatch.Stop();
        TimeSpan ts = _stopWatch.Elapsed;

        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
                                           ts.Hours, ts.Minutes, ts.Seconds,
                                           ts.Milliseconds / 10);
        Console.WriteLine(elapsedTime, "RunTime");
    }
}

private static void UsingStopWatchUsage()
{
    Console.WriteLine("ConsoleAutoStopWatch Used: ");
    using (new ConsoleAutoStopWatch())
    {
        Thread.Sleep(3000);
    }
}

Tanto probable que se ajuste a sus necesidades bien, pero yo diría que el uso StopWatch. ¿Por qué? Causa que está destinado para la tarea que está haciendo.

Tienes una clase que está construido para devolver la fecha / hora actual, que como es el caso puede ser utilizado para cosas de tiempo, y usted tiene una clase diseñada específicamente para las cosas de tiempo.

En este caso, sólo existen realmente las diferencias si necesita una precisión de milisegundos (en cuyo caso StopWatch es más preciso), sino como un principio general, si existe una herramienta específica para la tarea que está buscando, entonces es mejor uno a uso.

Tengo un poco de clase para hacer este tipo de cosas ad hoc. Se utiliza la clase cronómetro - c # micro perfomance de pruebas .

por ejemplo.

var tester = new PerformanceTester(() => SomeMethod());
tester.MeasureExecTime(1000);
Console.Writeline(string.Format("Executed in {0} milliseconds", tester.AverageTime.TotalMilliseconds));

El uso por debajo de código

DateTime dExecutionTime;
dExecutionTime = DateTime.Now;
      TimeSpan span = DateTime.Now.Subtract(dExecutionTime);
                  lblExecutinTime.Text = "total time taken " +   Math.Round(span.TotalMinutes,2) + " minutes .   >>---> " + DateTime.Now.ToShortTimeString();

Tomé respuesta de Hamish lo simplificó y lo hizo un poco más general en caso tienes que entrar a algún otro lugar:

public class AutoStopWatch : Stopwatch, IDisposable {

    public AutoStopWatch() {
        Start();
    }

    public virtual void Dispose() {
        Stop();
    }
}

 public class AutoStopWatchConsole : AutoStopWatch {

    private readonly string prefix;

    public AutoStopWatchConsole(string prefix = "") {
        this.prefix = prefix;
    }

    public override void Dispose() {
        base.Dispose();

        string format = Elapsed.Days > 0 ? "{0} days " : "";
        format += "{1:00}:{2:00}:{3:00}.{4:00}";

        Console.WriteLine(prefix + " " + format.Format(Elapsed.Days, Elapsed.Hours, Elapsed.Minutes, Elapsed.Seconds, Elapsed.Milliseconds / 10));
    }
}

private static void Usage() {

    Console.WriteLine("AutoStopWatch Used: ");
    using (var sw = new AutoStopWatch()) {
        Thread.Sleep(3000);

        Console.WriteLine(sw.Elapsed.ToString("h'h 'm'm 's's'"));
    }

    Console.WriteLine("AutoStopWatchConsole Used: ");
    using (var sw = new AutoStopWatchConsole()) {
        Thread.Sleep(3000);
    }

}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top