¿Qué tan preciso es System.Diagnostics.Stopwatch?

¿Qué tan preciso es System.Diagnostics.Stopwatch ? Estoy tratando de hacer algunas métricas para diferentes rutas de código y necesito que sea exacto. ¿Debo utilizar el cronómetro o hay otra solución más precisa?

Me han dicho que a veces el cronómetro proporciona información incorrecta.

¿Por qué no perfila su código en lugar de centrarse en los micro-puntos de referencia?

Hay algunos buenos perfiladores de código abierto como:

  • NProf
  • Prof-It para C #
  • NProfiler
  • ProfileSharp

Acabo de escribir un artículo que explica cómo se debe realizar una configuración de prueba para obtener una alta precisión (mejor que 0.1ms) fuera del cronómetro. Creo que debería explicar todo.

http://www.codeproject.com/KB/testing/stopwatch-measure-precise.aspx

La clase System.Diagnostics.Stopwatch mide con precisión el tiempo transcurrido, pero la forma en que funciona el método ElapsedTicks ha llevado a algunas personas a la conclusión de que no es precisa, cuando realmente solo tienen un error de lógica en su código.

La razón por la que algunos desarrolladores piensan que el Cronómetro no es exacto es porque los Tránsipes del Cronómetro NO SE ACUMULAN con los Tic en un DateTime. El problema surge cuando el código de la aplicación usa ElapsedTicks para crear un nuevo DateTime.

var watch = new Stopwatch(); watch.Start(); ... (perform a set of operations) watch.Stop(); var wrongDate = new DateTime(watch.ElapsedTicks); // This is the WRONG value. 

Si es necesario, la duración del cronómetro se puede convertir a DateTime de la siguiente manera:

 // This converts stopwatch ticks into DateTime ticks. // First convert to TimeSpan, then convert to DateTime var rightDate = new DateTime(watch.Elapsed.Ticks); 

Aquí hay un artículo que explica el problema con más detalle: http://geekswithblogs.net/BlackRabbitCoder/archive/2012/01/12/c.net-little-pitfalls-stopwatch-ticks-are-not-timespan-ticks. aspx

Primero, exacto no es, por supuesto, un concepto posible o significativo cuando se habla de tiempo o espacio, ya que ninguna medición empírica de una magnitud física puede pretender ser exacta.

En segundo lugar, el artículo de blog de David Bolton puede ser útil. Estoy citando:

Si esto fue sincronizado con el contador de alta resolución, será preciso a microsegundos. En realidad es preciso en nanosegundos (10-9 segundos, es decir, una milmillonésima de segundo), pero hay tantas otras cosas en juego que la precisión de los nanosegundos es realmente inútil. Al realizar el cronometraje o la evaluación comparativa del código, debe realizar una serie de ejecuciones y tomar el tiempo promedio, debido a otros procesos que se ejecutan en Windows, la cantidad de intercambio en el disco, etc., los valores entre dos ejecuciones pueden variar.

La clase Cronómetro devuelve diferentes valores bajo diferentes configuraciones ya que la frecuencia depende del hardware y sistema operativo instalados.

Usando la clase de cronómetro, solo podemos tener la estimación aproximada del tiempo de ejecución. Y para cada ejecución, devuelve un valor diferente, por lo que debemos tomar una media de ejecución diferente.

Más información: http://msdn.microsoft.com/en-us/library/system.diagnostics.stopwatch.aspx

Si quieres tiempos más precisos. Eche un vistazo al QueryPerformanceCounter. Enlace de MSDN para QueryPerformanceCounter . Una implementación ordenada se da aquí . El ejemplo carga coredll.dll para CE, para Windows debe cargar Kernel32.dll como se indica en la documentación de MSDN.

MSDN tiene algunos ejemplos del cronómetro. También lo tienen mostrando cuán preciso es dentro de Nanosegundos. ¡Espero que esto ayude!

Además de secundar el consejo de HUAGHAGUAH anterior, agregaría que debes ser MUY escéptico de los micro-puntos de referencia en general. Si bien las pruebas de rendimiento enfocadas de cerca tienen un lugar legítimo, es muy fácil ajustar un detalle sin importancia. Así que escriba y verifique el código que está diseñado para facilitar la lectura y la claridad, luego perfilelo para descubrir dónde están los puntos conflictivos (o si merece la pena preocuparse), y luego sintonice (solo) esas partes.

Recuerdo haber trabajado con un progtwigdor que micro-optimizó un poco de código que se ejecutó mientras el sistema esperaba la entrada de los humanos. ¡El ahorro de tiempo desapareció por completo en el lapso entre pulsaciones de teclas!