c# - tiempo - stopwatch()




¿DateTime.Now es la mejor manera de medir el rendimiento de una función? (10)

@ Sean Chambers

Para su información, la clase del temporizador .NET no es para diagnósticos, genera eventos en un intervalo preestablecido, como este (de MSDN ):

System.Timers.Timer aTimer;
public static void Main()
{
    // Create a timer with a ten second interval.
    aTimer = new System.Timers.Timer(10000);

    // Hook up the Elapsed event for the timer.
    aTimer.Elapsed += new ElapsedEventHandler(OnTimedEvent);

    // Set the Interval to 2 seconds (2000 milliseconds).
    aTimer.Interval = 2000;
    aTimer.Enabled = true;

    Console.WriteLine("Press the Enter key to exit the program.");
    Console.ReadLine();
}

// Specify what you want to happen when the Elapsed event is 
// raised.
private static void OnTimedEvent(object source, ElapsedEventArgs e)
{
    Console.WriteLine("The Elapsed event was raised at {0}", e.SignalTime);
}

Entonces, esto realmente no te ayuda a saber cuánto tiempo tomó algo, solo que ha pasado una cierta cantidad de tiempo.

El temporizador también se expone como un control en System.Windows.Forms ... lo puede encontrar en la caja de herramientas del diseñador en VS05 / VS08

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

¿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);

Acabo de encontrar una publicación en el blog de Vance Morrison sobre una clase de CodeTimer que él escribió, que hace que usar StopWatch sea ​​más fácil y hace algunas cosas interesantes al lado.


Esta es la forma correcta:

using System;
using System.Diagnostics;

class Program
{
    public static void Main()
    {
        Stopwatch stopWatch = Stopwatch.StartNew();

            // some other code

        stopWatch.Stop();

        // this not correct to get full timer resolution
        Console.WriteLine("{0} ms", stopWatch.ElapsedMilliseconds);

        // Correct way to get accurate high precision timing
        Console.WriteLine("{0} ms", stopWatch.Elapsed.TotalMilliseconds);
    }
}

Para obtener más información, utilice Usar cronómetro en lugar de DataTime para obtener un contador de rendimiento preciso .


Esto no es lo suficientemente profesional:

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

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

Una versión más confiable es:

PerformWork();

int repeat = 1000;

Stopwatch sw = Stopwatch.StartNew();
for (int i = 0; i < repeat; i++)
{
   PerformWork();
}

sw.Stop();

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

En mi código real, agregaré GC.Collect call para cambiar el montón administrado a un estado conocido, y agregaré Sleep call para que diferentes intervalos de código se puedan separar fácilmente en el perfil de ETW.


La forma en que uso dentro de mis programas es usando la clase StopWatch como se muestra aquí.

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


// Critical lines of code

long elapsedMs = sw.Elapsed.TotalMilliseconds;

La funcionalidad del stopwatch sería mejor (mayor precisión). Sin embargo, también recomiendo descargar uno de los perfiladores populares ( DotTrace y ANTS son los que más he usado ... la versión de prueba gratuita de DotTrace es completamente funcional y no es tan molesta como algunos de los otros).


No, no es. Usa el Stopwatch (en System.Diagnostics )

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

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

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

Vale la pena mencionar que DateTime.Now menudo es un poco más lento que DateTime.UtcNow debido al trabajo que se tiene que hacer con las zonas DST , DST y similares.

DateTime.UtcNow generalmente tiene una resolución de 15 ms. Vea la publicación del blog de John Chapman sobre DateTime.Now precisión para un gran resumen.

Curiosidades interesantes: el cronómetro se DateTime.UtcNow en DateTime.UtcNow si su hardware no admite un contador de alta frecuencia. Puede verificar si el Cronómetro usa hardware para lograr una alta precisión al mirar el campo estático Stopwatch.IsHighResolution .


Si quieres algo rápido y sucio, te sugiero que uses Cronómetro para 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 usar un perfilador de terceros, como ANTS .


Utilice la clase System.Diagnostics.Stopwatch.

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

// Do some code.

sw.Stop();

// sw.ElapsedMilliseconds = the time your "do some code" took.

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

También muestra que en algunos casos (cuando el contador de rendimiento no existe), el Cronómetro está utilizando DateTime.UtcNow + un procesamiento adicional. Debido a eso, es obvio que en ese caso DateTime.UtcNow es la mejor opción (porque otros lo usan + algún procesamiento)

Sin embargo, según parece, el contador casi siempre existe; consulte la Explicación sobre el contador de rendimiento de alta resolución y su existencia relacionada con .NET Stopwatch? .

Aquí hay un gráfico de rendimiento. Observe cómo el bajo rendimiento que tiene UtcNow en comparación con las alternativas:

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

Una cosa en la que el Stopwatch es mejor es que proporciona mediciones de tiempo de mayor resolución. Otra es su naturaleza más OO. Sin embargo, crear una envoltura OO alrededor de UtcNow no puede ser difícil.





timer