tiempo stop startnew sharp create contador c# .net performance datetime timer

c# - stop - ¿DateTime.Now es la mejor manera de medir el rendimiento de una función?



stopwatch timer c# (15)

@ 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.


Es útil insertar su código de referencia en una clase / método de utilidad. La clase StopWatch no necesita ser Disposed o Stopped en caso de error. Por lo tanto, el código más simple para medir el tiempo de 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 muestra código de llamada

public void Execute(Action action) { var time = action.Benchmark() log.DebugFormat(“Did action in {0} ms.”, time); }


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.


He hecho muy poco de este tipo de comprobación de rendimiento (tiendo a pensar que "esto es lento, hacerlo más rápido"), así que casi siempre he ido con esto.

Un google revela una gran cantidad de recursos / artículos para la verificación del rendimiento.

Muchos mencionan el uso de pinvoke para obtener información de rendimiento. Muchos de los materiales que estudio solo mencionan el uso de perfmon ..

Editar:

Visto las charlas de StopWatch .. Niza! He aprendido algo :)

Esto parece un buen artículo.


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).


Lo mismo ocurre con el cronómetro.

Con respecto a la medición del rendimiento, también debe verificar si su "// Algunos procesos de ejecución" es un proceso muy corto.

También tenga en cuenta que la primera ejecución de su "// Algunos procesos de ejecución" podría ser mucho más lenta que las ejecuciones posteriores.

Normalmente, pruebo un método ejecutándolo 1000 veces o 1000000 veces en un bucle y obtengo datos mucho más precisos que ejecutarlo una vez.


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 .


Todas estas son formas excelentes de medir el tiempo, pero esa es solo una forma muy indirecta de encontrar cuellos de botella.

La forma más directa de encontrar un cuello de botella en un hilo es hacerlo funcionar, y mientras hace lo que sea que lo haga esperar, deténgalo con una tecla de pausa o pausa. Haga esto varias veces. Si su cuello de botella toma X% de tiempo, X% es la probabilidad de que lo atrape en el acto en cada instantánea.

Aquí hay una explicación más completa de cómo y por qué funciona.


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.


Visual Studio Team System tiene algunas características que pueden ayudar con este problema. Esencialmente, puede escribir pruebas unitarias y combinarlas en diferentes escenarios para ejecutar su software como parte de una prueba de carga o carga. Esto puede ayudar a identificar las áreas de código que más impactan el rendimiento de sus aplicaciones.

El grupo de Patrones y Prácticas de Microsoft tiene alguna guía en la Guía de Pruebas de Rendimiento del Sistema del Equipo de Visual Studio .