Секундомер против использования System.DateTime.Now для синхронизации событий

Я хотел отслеживать производительность моего кода, поэтому я сохранил время начала и окончания, используя System.DateTime.Now. Я взял разницу между ними как время моего кода для выполнения.

Я заметил, что разница оказалась неточной. Поэтому я попытался использовать объект Stopwatch. Это оказалось намного точнее.

Может ли кто-нибудь сказать мне, почему Stopwatch будет более точным, чем вычисление разницы между начальным и конечным временем с помощью System.DateTime.Now?

Кстати, я не говорю о десятых процента. Я получаю разницу в 15-20%.

Ответ 1

По MSDN:

Секундомер измеряет прошедшее время, подсчитывая отметки таймера в базовом таймерном механизме. Если установленная аппаратная и операционная система поддерживает счетчик производительности с высоким разрешением, то класс секундомера использует этот счетчик для измерения прошедшего времени. В противном случае класс секундомера использует системный таймер для измерения прошедшего времени. Используйте поля Frequency и IsHighResolution для определения точности и разрешения реализации синхронизации секундомера.

Он использует более высокое разрешение/точность, чем DateTime.Now.

Вы также можете проверить эти ссылки:

Environment.TickCount против DateTime.Now

Является ли DateTime.Now лучшим способом измерения производительности функции?

DateTime достаточно хорош для точности ко второму, возможно, но что-то кроме этого я бы рекомендовал StopWatch.

Ответ 2

Лучше использовать класс секундомера, потому что он намного точнее, чем вычитание значений DateTime:

Stopwatch s = Stopwatch.StartNew();
// Tested code here
s.Stop();
Console.WriteLine("Elapsed Time: {0} ms", s.ElapsedMilliseconds);

К сожалению, этого простого фрагмента кода будет недостаточно, чтобы получать точные измерения большую часть времени, потому что у вас много активности под капотом ОС, что может украсть некоторое время процессора и замедлить выполнение ваш код. Вот почему лучше всего выполнять тесты несколько раз, а затем удалять наименьшее и самое высокое время. Для этого puprose это хорошее решение, чтобы иметь метод, который выполняет проверенный код несколько раз, удаляет самое низкое и наибольшее время и вычисляет среднее время. Я опубликовал образец метода тестирования в своем блоге.

Ответ 3

эта производительность функции синхронизации ссылается на вашу точную проблему, в частности на этот параграф:

Проблема заключается в том, что согласно MSDN разрешение функции DateTime.Now составляет 10+ миллисекунд, и нам нужно позвонить ему дважды! Таким образом, это приведет к качанию 20 + ms в вашем измерении времени выполнения. Поскольку наши вызовы функций часто бывают намного быстрее, чем это 20-секундное окно, это не достаточно хорошо.

EDIT: Это похоже на второй DateTime.Now вызывается в другое время, чем при завершении метода секундомера.