Necesito encontrar un cuello de botella y necesito medir el tiempo con la mayor precisión posible.
¿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);
Respuestas:
No, no es. Use el cronómetro (en
System.Diagnostics
)El cronómetro verifica automáticamente la existencia de temporizadores de alta precisión.
Vale la pena mencionar que a
DateTime.Now
menudo es un poco más lento queDateTime.UtcNow
debido al trabajo que se debe hacer con las zonas horarias , DST y demás .DateTime.UtcNow normalmente 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 vuelve a funcionar
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 mirando el cronómetro de campo estático . IsHighResolution .fuente
PerformWork()
es muy corto, puede llamarlo repetidamente y calcular el promedio del lote de llamadas. Además, programe un lote completo de llamadas en lugar de iniciar / detener suStopwatch
para evitar un efecto estroboscópico que enturbiará sus mediciones de tiempo.Si desea algo rápido y sucio, sugeriría usar el cronómetro en su lugar para un mayor grado de precisión.
Alternativamente, si necesita algo un poco más sofisticado, probablemente debería considerar usar un perfilador de terceros como ANTS .
fuente
En este artículo se dice que en primer lugar es necesario comparar tres alternativas,
Stopwatch
,DateTime.Now
YDateTime.UtcNow
.También muestra que en algunos casos (cuando el contador de rendimiento no existe) el cronómetro está usando DateTime.UtcNow + algún procesamiento adicional. Por eso es obvio que en ese caso DateTime.UtcNow es la mejor opción (porque otros lo usan + algún procesamiento)
Sin embargo, como resultado, el contador casi siempre existe: consulte la explicación sobre el contador de rendimiento de alta resolución y su existencia relacionada con el cronómetro .NET. .
Aquí hay un gráfico de rendimiento. Observe cómo el bajo costo de rendimiento que UtcNow ha comparado 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
Stopwatch
es mejor porque proporciona mediciones de tiempo de mayor resolución. Otro es su naturaleza más OO. Sin embargo, crear un contenedor OOUtcNow
no puede ser difícil.fuente
Es útil insertar su código de evaluación comparativa en una clase / método de utilidad. La
StopWatch
clase no necesita serDisposed
oStopped
por error. Entonces, el código más simple para cronometrar alguna acción esCódigo de llamada de muestra
Aquí está la versión del método de extensión
Y muestra de código de llamada
fuente
Elapsed.TotalMilliseconds
para mayor precisión. Vea esta pregunta también stackoverflow.com/questions/8894425/…La funcionalidad del cronómetro sería mejor (mayor precisión). Sin embargo, también recomendaría descargar uno de los perfiladores populares ( DotTrace y ANTS son los que más he usado ... la versión de prueba gratuita para DotTrace es completamente funcional y no molesta como algunos de los otros).
fuente
Utilice la clase System.Diagnostics.Stopwatch.
fuente
Ídem Cronómetro, es mucho mejor.
Con respecto a la medición del rendimiento, también debe verificar si su "// Algún proceso de ejecución" es un proceso muy corto.
También tenga en cuenta que la primera ejecución de su "// Algún proceso de ejecución" podría ser mucho más lenta que las ejecuciones posteriores.
Por lo general, 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.
fuente
Todas estas son excelentes formas 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 está haciendo lo que sea que lo haga esperar, deténgalo con una tecla de pausa o pausa. Haz 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.
fuente
@ Sean Chambers
Para su información, la clase .NET Timer no es para diagnósticos, genera eventos en un intervalo preestablecido, como este (desde MSDN ):
Entonces, esto realmente no 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 ... puede encontrarlo en su caja de herramientas de diseño en VS05 / VS08
fuente
Esta es la forma correcta:
Para obtener más información, utilice Usar cronómetro en lugar de DataTime para obtener un contador de rendimiento preciso .
fuente
Visual Studio Team System tiene algunas características que pueden ayudar con este problema. Esencialmente, puede escribir pruebas unitarias y mezclarlas en diferentes escenarios para ejecutarlas contra su software como parte de una prueba de esfuerzo o carga. Esto puede ayudar a identificar las áreas de código que más afectan el rendimiento de sus aplicaciones.
El grupo de Patrones y Prácticas de Microsoft tiene alguna orientación en la Guía de pruebas de rendimiento del sistema de equipo de Visual Studio .
fuente
Acabo de encontrar una publicación en el blog de Vance Morrison sobre una clase de CodeTimer que escribió que hace que usar sea
StopWatch
más fácil y que haga algunas cosas interesantes aparte .fuente
Esto no es lo suficientemente profesional:
Una versión más confiable es:
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 se puedan separar fácilmente diferentes intervalos de código en el perfil ETW.
fuente
He hecho muy poco de este tipo de comprobación de rendimiento (tiendo a pensar "esto es lento, hazlo más rápido"), así que casi siempre he seguido con esto.
Un google revela muchos recursos / artículos para la verificación del rendimiento.
Muchos mencionan el uso de pinvoke para obtener información sobre el rendimiento. Muchos de los materiales que estudio solo mencionan realmente el uso de perfmon.
Editar:
Visto las conversaciones de StopWatch .. ¡Bien! He aprendido algo :)
Este parece un buen artículo.
fuente
La forma en que uso dentro de mis programas es usando la clase StopWatch como se muestra aquí.
fuente