Значение счетчика AverageTimer32 становится равным нулю - PullRequest
6 голосов
/ 15 марта 2012

Я написал фрагмент кода, подобный приведенному ниже:

Для тестирования я вызываю метод ComputeAndLog, и в мониторе производительности я вижу ненулевое среднее значение.Однако, как только я заканчиваю тестирование, среднее значение счетчика производительности падает до нуля.Любая идея, почему это так?

Возможно, я использую неправильные счетчики?

Требование, которое у меня есть, состоит в том, что у меня есть функция, и я должен вычислить это в среднем, сколько времениФункция занимает для завершения.Примерно так:

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

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

Спасибо xoxo

Ответы [ 2 ]

5 голосов
/ 31 июля 2012

AverageTimer32 / 64 не вычисляет среднее значение всех измерений, которые вы выполняете.Вместо этого он обеспечивает соотношение ваших измерений к количеству измеренных вами операций.

В основном проблема с вашим кодом заключается в том, что вы используете новый таймер каждый раз, когда выполняете измерение.

Чтобы понять, как работает AverageTimer, было бы полезно понять формулу, лежащую в основе этого.Это также объясняет, почему для использования AverageTimer требуется AverageBase.

Формула для AverageTimer следующая:

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

с текущими показаниями

  • N1в момент времени t (AverageTimer)
  • N0, считываемый ранее, в t - 1 (AverageTimer)
  • Счетчик тока B1 в момент времени t (AverageBase)
  • Счетчик B0 ранее, в момент времени t -1 (Средняя база)
  • F Коэффициент для расчета тиков / секунд

В двух словах, формула берет текущее время в тиках и вычитает предыдущее.Результат, деленный на коэффициент F, дает вам время выполнения операции с момента последнего измерения, выполненного в t-1.

Теперь вы делите это на текущий счетчик минус счетчик ранее.Это может быть обычно один.В результате у вас есть среднее время вашей операции для одного измерения.

Используя AverageBase, вы можете перешагивать различные точки измерения.Вспомните случай, когда вы можете установить счетчик только для каждой десятой выполняемой вами операции.Со времени вашего последнего измерения вы увеличиваете AverageTimer на новое измерение времени для всех десяти операций, но увеличиваете AverageBase на десять.В конечном итоге вы получите среднее время для одной операции (даже если вы измерили все десять вызовов операции).

Глядя на пример кода, вы всегда отправляете разницу от начала таймера до конца таймера.Пусть это будет последовательность чисел, таких как 10, 9, 8, 7, 6, при увеличении AverageBase на 1.

Для второго известного измерения вы получите следующий результат:

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

Если F для простоты равен 1, вы получите -1 в качестве результата.

Однако правильные значения для отправки должны быть

10, 19, 27, 34, 40

Снова тот же пример, мы получим

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

Опять же, если F равен 1, у вас будет среднее время 9 для вашей операции.Как видите, следующее измеренное значение должно быть больше предыдущего, поэтому AverageTimer работает правильно.

В вашем примере вы можете использовать глобальный секундомер.Вместо запуска нового используйте Start () (не Restart ()).Как видно выше, счетчик рассчитает разницу во времени внутри страны.Таким образом, вы получите правильные измерения.

Переход к нулю также имеет смысл, когда вы закончите тестирование или завершите свою программу, счетчик, вероятно, будет закрыт и больше не будет давать никаких значений.Вы можете сделать это вручную, вызвав метод Close () на счетчике.

0 голосов
/ 07 июля 2013

У меня была похожая проблема. У меня был хороший вывод в PerformanceMonitor от AverangeCounter. Но в программе операция NextValue всегда возвращает 0. Кстати, в счетчике ElapsedTime возвращается то же значение операции, что и мне.

Тогда я понимаю ядро ​​AverageTimer32 (надеюсь). Вы не должны надеяться, что AverageTimer32 покажет усредненное время некоторой работы. Это просто таймер, который показывает среднее время одной операции и показывает его. Если работа не ведется, то времени работы не существует, и в качестве значения счетчика у вас будет 0.

если я беру NextValue каждый раз, когда добавляю тики для счетчика, он возвращает счетчик секунд (как я понимаю, это возвращаемое последнее значение, а не среднее значение. Счетчик AverageTimer32 имеет имя, которое любой может неправильно понять). И если я кеширую его, я могу преобразовать его в более читабельную форму и использовать в качестве значения счетчика в программе (если вы спросите NextValue сразу после этого во второй раз, вы получите 0).

Также я хочу исправить предыдущий ответ. Вы должны использовать

10, 9, 8, 7, 6

вместо

10, 19, 27, 34, 40

при использовании метода IncreaseBy и

10, 19, 27, 34, 40

когда вы устанавливаете Stopwatch.GetTimestamp () вручную в RawValue.

...