2012-03-14 21 views
5

He escrito un pedazo de código como este a continuación:valor del contador se convierte en cero AverageTimer32

Para las pruebas que llamo el método ComputeAndLog y en el monitor de rendimiento puedo ver el valor medio distinto de cero. Sin embargo, tan pronto como termine mi prueba, el valor del contador de rendimiento promedio cae a cero. ¿Alguna idea de por qué es así?

Probablemente estoy usando los contadores equivocados?

El requisito que tengo es que tengo una función y tengo que calcular eso en promedio, cuánto tiempo tarda esa función en completarse. Algo parecido a continuación:

void ComputeAndLog() 
{ 
    Stopwatch stopWatch = Stopwatch.StartNew(); 
    FunctionWhoseAveragetTimeIsToBeMeasured(); 
    write_counter(stopWatch.ElapsedTicks); 
} 

void write_counter(long timeForCompletion) 
{ 
    averageTimeCounter.IncrementBy(timeForCompletion); 
    averageBaseCounter.Increment(); 
} 

Gracias xoxo

+1

Sócrates: ¿cuál es el promedio sin incrementos? –

+0

Lo siento, no recibí esa pregunta. ¿Probablemente estoy usando el contador equivocado? He actualizado el código inicial con el requisito que tengo. –

+0

Es la duración promedio durante el tiempo transcurrido desde la última medición. Si no está registrando nada, se convertirá en cero ya que la duración promedio no está definida (simplificada a cero). – Guvante

Respuesta

4

El AverageTimer32/64 no calcula el promedio de todas las mediciones que se realizan. En cambio, proporciona la ración de sus mediciones al número de operaciones que midió.

Básicamente, el problema con su código es el hecho de que está usando un nuevo temporizador cada vez que realiza una medición.

Para comprender cómo funciona el AverageTimer, podría ser útil comprender la fórmula que lo respalda. Esto también responde por qué uno necesita un AverageBase para usar un AverageTimer.

La fórmula para el AverageTimer es la siguiente:

((N1 - N0)/F)/(B1 - B0) 

con

  • lectura actual N1 en el tiempo t (AverageTimer)
  • N0 lectura antes, en t - 1 (AverageTimer)
  • Contador de corriente B1 en t (AverageBase)
  • Contador de B0 antes, en t - 1 (Average Base)
  • F Factor para calcular ticks/segundo

En pocas palabras el formular toma el tiempo actual en las garrapatas y resta la anterior. El resultado dividido por el factor F le da el tiempo de operación desde la última medición tomada en t-1.

Ahora divida esto por el contador actual menos el contador anterior. Esto podría ser generalmente uno. Como resultado, tiene el tiempo promedio de su operación para una medición.

Al utilizar AverageBase ahora puede pasar por varios puntos de medición. Piense en un caso en el que puede configurar el contador solo cada décima operación que realice. Desde su última medición, incrementaría el Temporizador Promedio en la nueva medición de tiempo para las diez operaciones, pero aumentaría la Base Promedio en diez. Eventualmente, recibirá el tiempo promedio para una operación (incluso si ha medido sobre las diez llamadas de operación).

En cuanto a su ejemplo de código, siempre envía la diferencia desde el inicio del temporizador hasta el final del temporizador. Deje que esto sea una serie de números como 10, 9, 8, 7, 6 mientras aumenta el AverageBase en 1.

para la segunda medición sabes recibirá el siguiente resultado:

(9 - 10)/F/(10) = -1/F/1

Con F siendo 1 por simplicidad obtendrás -1 como resultado.

Los valores correctos para presentar sin embargo deben ser

10, 19, 27, 34, 40

de nuevo el mismo ejemplo vamos a obtener

(19 - 10)/F/(1 - 0) = 9/F/1

De nuevo, con F es 1, tendrá un tiempo promedio de 9 para su operación. Como puede ver, el próximo valor medido debe ser mayor que el anterior para que el Temporizador promedio funcione correctamente.

En su ejemplo, puede utilizar un cronómetro global. En lugar de iniciarlo nuevo, use Start() (no Restart()). Como se ve arriba, el contador calculará la diferencia en el tiempo internamente. De esa forma obtendrás las medidas correctas.

Ir a cero también tiene sentido, una vez que haya terminado con su prueba o su programa termine, el contador probablemente se cerrará y ya no proporcionará ningún valor. Puede hacerlo manualmente llamando al método Close() en el contador.

+0

No creo que esta respuesta sea correcta. En la pregunta, N es siempre * incrementado * por los ticks transcurridos. Por lo tanto, no es posible que N1 sea menor que N0 (como en el primer ejemplo). Y así la conclusión restante es (probablemente) también incorrecta. –

0

Tuve un problema similar. Tuve un buen rendimiento en PerformanceMonitor de AverangeCounter. Pero en el programa una operación NextValue siempre devuelve 0. Por cierto en el contador ElapsedTime el mismo valor de retorno de operación que yo quiero.

Luego entiendo el núcleo de AverageTimer32 (espero). No debe esperar que AverageTimer32 muestre el tiempo promedio de algún trabajo. Es solo un temporizador ese tiempo promedio para una operación y lo muestra. Si no se está trabajando, no existe tiempo de operación y tendrá 0 como valor de contador.

si uso NextValue cada vez que agrego ticks para contrarrestarlo, devuelvo recuentos de segundos (ya que entiendo que es el último valor de retorno, no el valor promedio. Un contador AverageTimer32 tiene un nombre que cualquiera puede malinterpretar). Y si lo guardo en caché, entonces puedo convertirlo en una forma más legible y usarlo como valor de contador en el programa (si le preguntas a NextValue inmediatamente después de eso en la segunda vez recibes 0).

También quiero corregir la respuesta anterior. Debe utilizar

10, 9, 8, 7, 6

en lugar de

10, 19, 27, 34, 40

cuando se utiliza método IncreaseBy y

10, 19, 27, 34, 40

cuando establece Stopwatch.GetTimestamp() manualmente en RawValue.

Cuestiones relacionadas