2010-09-07 4 views
5

Lo que quiero decir es ...¿Es esta una buena manera de verificar la cantidad de tiempo que se tardó en ejecutar algún código en C#?

obtener el tiempo, ejecute el código, obtener el tiempo, comparar el tiempo y obtener el segundo Salida:

estoy haciendo esto correcto?

DateTime timestamp = DateTime.Now; 
//...do the code... 
DateTime endstamp = DateTime.Now; 

string results = ((endstamp.ticks - timestamp.ticks)/10000000).ToString(); 
+0

Las mejores herramientas para esto son herramientas de perfil real como RedGate Profiler o una que viene con una de las versiones de Visual Studio. Por falta de eso, lo que dijo Anthony sería su mejor opción –

+1

@George - Para operaciones grandes o ver dónde se puede pasar el tiempo, pero para fragmentos de código cortos, ver cuál es la forma más rápida de hacer algo 10.000 veces, por ejemplo ... los perfiladores interfieren activamente y probablemente no sean la mejor manera de obtener resultados precisos. –

+0

Bastante, buen punto. –

Respuesta

6

No. Utilice la clase System.Diagnostics.Stopwatch en su lugar. DateTime.Now no tiene el nivel de precisión que usted desea (aunque la estructura DateTime es bastante precisa, en sí misma).

Stopwatch watch = new Stopwatch(); 
watch.Start(); 
// do stuff 
watch.Stop(); 
long ticks = watch.ElapsedTicks; 
+0

¿alguna muestra de implementación? – BigOmega

+0

@Ryan, muestra adicional. –

+4

De hecho, DateTime tiene mucha * precisión * pero no tiene un nivel acorde de * precisión *. Consulte http://blogs.msdn.com/b/ericlippert/archive/2010/04/08/precision-and-accuracy-of-datetime.aspx para obtener algunas ideas al respecto. –

13

Debe utilizar Stopwatch para esto, por ejemplo:

var sw = Stopwatch.StartNew(); 
//...do the code... 
sw.Stop(); 
var result = sw.ElapsedTicks; //ticks it took 
//or less accurate/for bigger tasks, sw.ElapsedMilliseconds 

vez haya incluido en Brian @ 's mejora de los comentarios.

+5

+1. Un atajo es: 'var sw = Stopwatch.StartNew();' que simplemente une las dos primeras líneas en una sola. Además, a menos que tome una pequeña cantidad de tiempo, prefiero 'sw.ElapsedMilliseconds' ya que significa más para mí que ticks. –

+0

@Brian - Lo he usado 1000 veces y * nunca * he notado '.StartNew()', sombreros señor. –

+0

El cronómetro también fue muy bien escrito por [James Michael] (http://geekswithblogs.net/BlackRabbitCoder/archive/2010/08/26/c.net-five-little-wonders-that-make-code-better-1 -of.aspx) y publicitado por [ScottGu] (http://weblogs.asp.net/scottgu/archive/2010/08/29/august-29th-links-net-asp-net-iis-express-silverlight- windows-phone-7.aspx) hace un par de semanas – slugster

0

Es probablemente muy bien, pero tenga en cuenta que hay varios medios para "la cantidad de tiempo que se tardó en ejecutar algún código". Lo que tienes allí es el tiempo del reloj de pared: la cantidad de tiempo que pasó en el mundo entre la primera y la segunda llamada al DateTime.Now (aproximadamente). Esto incluirá el tiempo dedicado a esperar bloqueos o acceso al disco, el tiempo dedicado a ejecutar otros hilos que no contienen su código, etc.

1

Obviamente, los procesos arbitarios que se ejecutan en su máquina probablemente distorsionarán el resultado obtenido.
un cronómetro es una buena solución, como se indica en MSDN:

El cronómetro mide el tiempo transcurrido contando pasos de temporizador en el mecanismo temporizador subyacente. Si el hardware y el sistema operativo instalados admiten un contador de rendimiento de alta resolución, la clase Cronómetro usa ese contador para medir el tiempo transcurrido. De lo contrario, la clase Cronómetro utiliza el temporizador del sistema para medir el tiempo transcurrido. Utilice los campos Frecuencia e IsHighResolution para determinar la precisión y la resolución de la implementación del tiempo del cronómetro.

La clase Cronómetro ayuda a manipular los contadores de rendimiento relacionados con la temporización dentro del código administrado. Específicamente, el campo Frecuencia y el método GetTimestamp se pueden usar en lugar de las API Win32 no administradas QueryPerformanceFrequency y QueryPerformanceCounter.

0

Eso inflará sus tiempos solo un poco, pero en general funciona. También puede seguir principios orientados a aspectos y adoptar algo como log4net para obtener esta funcionalidad sin tener que codificarla en todas partes.

Here is an article en él.

11

Como mucha gente ha notado, la clase de cronómetro de alta precisión está diseñada para responder la pregunta "¿cuánto tiempo tomó esto?" mientras que la clase DateTime está diseñada para responder a la pregunta "¿cuándo comienza Doctor Who?" Use la herramienta correcta para el trabajo.

Sin embargo, hay más en el problema de medir correctamente el tiempo transcurrido que simplemente obtener el temporizador correcto. También debe asegurarse de que está midiendo lo que realmente desea medir.Por ejemplo, considere:

// start the timer 
M(); 
// stop the timer 
// start another timer 
M(); 
// stop the timer 

¿Habrá una diferencia significativa entre los tiempos de las dos llamadas? Posiblemente sí. Recuerde, la primera vez que se llama un método , el jitter debe compilarlo desde IL en el código de máquina. Eso lleva tiempo. La primera llamada a un método puede ser en muchos casos veces más larga que todas las llamadas subsiguientes juntas.

Entonces, ¿qué medida es "correcta"? La primera medición? ¿El segundo? ¿Un promedio de ellos? Depende de lo que intente optimizar para. Si está optimizando para inicio rápido, entonces se preocupa mucho por el tiempo de jit. Si está optimizando para número de páginas idénticas servidas por segundo en un servidor calentado, entonces no le importa en absoluto el tiempo de jit y debería diseñar sus pruebas en y no en medirlo. Asegúrese de estar midiendo para lo que realmente está optimizando.

1

Las sugerencias dadas en las respuestas anteriores funcionarán para mediciones simples. Si necesita algo más avanzado, es posible que desee utilizar un generador de perfiles (hay comerciales y gratuitos, como equatec).

Cuestiones relacionadas