Мне нужно найти узкое место и нужно точно измерить время.
Является ли следующий фрагмент кода лучшим способом измерения производительности?
DateTime startTime = DateTime.Now;
// Some execution process
DateTime endTime = DateTime.Now;
TimeSpan totalTimeTaken = endTime.Subtract(startTime);
Ответы:
Нет, это не так. Используйте секундомер (в
System.Diagnostics
)Секундомер автоматически проверяет наличие высокоточных таймеров.
Стоит отметить, что
DateTime.Now
часто это происходит немного медленнее, чемDateTime.UtcNow
из-за работы с часовыми поясами, летним временем и т. Д.DateTime.UtcNow обычно имеет разрешение 15 мс. Посмотрите сообщение в блоге Джона Чепмена о
DateTime.Now
точности для отличного резюме.Интересные мелочи: секундомер возвращается,
DateTime.UtcNow
если ваше оборудование не поддерживает высокочастотный счетчик. Вы можете проверить, использует ли секундомер аппаратное обеспечение для достижения высокой точности, посмотрев на статическое поле Stopwatch.IsHighResolution .источник
PerformWork()
очень мало, вы можете звонить ему несколько раз и вычислять среднее значение для пакета вызовов. Кроме того, измеряйте целую серию вызовов вместо того, чтобы начинать / останавливать свой,Stopwatch
чтобы избежать строб-эффекта, который испортит ваши измерения времени.Если вы хотите что-то быстрое и грязное, я бы предложил вместо этого использовать секундомер для большей точности.
В качестве альтернативы, если вам нужно что-то более сложное, вы, вероятно, должны рассмотреть возможность использования стороннего профилировщика, такого как ANTS .
источник
В этой статье говорится, что в первую очередь вам нужно сравнить три альтернативы
Stopwatch
,DateTime.Now
ANDDateTime.UtcNow
.Это также показывает, что в некоторых случаях (когда счетчик производительности не существует) Секундомер использует DateTime.UtcNow + некоторая дополнительная обработка. Из-за этого очевидно, что в этом случае DateTime.UtcNow является лучшим вариантом (потому что другие используют его + некоторая обработка)
Однако, как оказалось, счетчик почти всегда существует - см. Объяснение о счетчике производительности с высоким разрешением и его существовании, связанном с .NET Stopwatch? ,
Вот график производительности. Обратите внимание, как низкая стоимость производительности UtcNow по сравнению с альтернативами:
Ось X - это размер выборки, а ось Y - относительное время примера.
Одна вещь ,
Stopwatch
лучше в том , что она обеспечивает более высокие измерения времени разрешения. Другой - это его более оо-природа. Тем не менее, создание OO-оболочкиUtcNow
не может быть трудным.источник
Полезно поместить ваш код тестирования в служебный класс / метод.
StopWatch
Класс не должен бытьDisposed
илиStopped
в случае ошибки. Так, простейший код времени некоторые действия являетсяОбразец кода вызова
Вот версия метода расширения
И пример кода вызова
источник
Elapsed.TotalMilliseconds
для более высокой точности. Смотрите этот вопрос тоже stackoverflow.com/questions/8894425/…Функциональность секундомера была бы лучше (более высокая точность). Я также рекомендовал бы просто загрузить один из популярных профилировщиков (тем не менее , я использовал DotTrace и ANTS ... бесплатная пробная версия для DotTrace полностью функциональна и не раздражает, как некоторые другие).
источник
Используйте класс System.Diagnostics.Stopwatch.
источник
То же самое Секундомер, это намного лучше.
Что касается измерения производительности, вы должны также проверить, является ли ваш "// Some Execution Process" очень коротким процессом.
Также имейте в виду, что первый запуск "// Some Execution Process" может быть намного медленнее, чем последующие.
Обычно я тестирую метод, выполняя его 1000 или 1000000 циклов, и получаю гораздо более точные данные, чем один раз.
источник
Все это отличные способы измерения времени, но это только очень косвенный способ найти узкие места.
Самый прямой способ найти узкое место в потоке - это запустить его, и пока он делает все, что заставляет вас ждать, остановите его клавишей паузы или прерывания. Сделайте это несколько раз. Если ваше узкое место занимает X% времени, X% - это вероятность того, что вы поймаете его в действии на каждом снимке.
Вот более полное объяснение того, как и почему это работает
источник
@ Шон Чемберс
К вашему сведению, класс .NET Timer не предназначен для диагностики, он генерирует события с заданным интервалом, например так (из MSDN ):
Так что это действительно не поможет вам узнать, сколько времени заняло что-то, просто прошло определенное количество времени.
Таймер также отображается в качестве элемента управления в System.Windows.Forms ... его можно найти в наборе инструментов вашего дизайнера в VS05 / VS08
источник
Это правильный путь:
Для получения дополнительной информации перейдите к использованию секундомера вместо DataTime для получения точного счетчика производительности .
источник
Visual Studio Team System имеет некоторые функции, которые могут помочь с этой проблемой. По сути, вы можете писать модульные тесты и смешивать их в различных сценариях, чтобы запускать их против вашего программного обеспечения в рамках стресс-теста или нагрузочного теста. Это может помочь определить области кода, которые больше всего влияют на производительность ваших приложений.
У группы Microsoft Patterns and Practices есть некоторые рекомендации в Руководстве по тестированию производительности системы Visual Studio Team .
источник
Я только что нашел пост в блоге Вэнса Моррисона о классе CodeTimer, который он написал, который облегчает использование
StopWatch
и делает некоторые полезные вещи на стороне.источник
Это не достаточно профессионально:
Более надежная версия:
В своем реальном коде я добавлю вызов GC.Collect для изменения управляемой кучи в известное состояние и добавлю вызов режима ожидания, чтобы различные интервалы кода можно было легко разделить в профиле ETW.
источник
Я очень мало проверил такого рода проверку производительности (я склонен думать, что «это медленно, сделайте это быстрее»), поэтому я почти всегда с этим справлялся.
Google показывает много ресурсов / статей для проверки производительности.
Многие упоминают об использовании pinvoke для получения информации о производительности. Множество материалов, которые я изучаю, на самом деле упоминают только использование perfmon.
Редактировать:
Видел разговоры о StopWatch .. Здорово! Я кое-чему научился :)
Это похоже на хорошую статью
источник
В моих программах я использую класс StopWatch, как показано здесь.
источник