Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Учимся писать положительные C#-бенчмарки

Anna | 17.06.2014 | нет комментариев
У меня с коллегами неоднократно появляются разговоры о быстродействии того либо другого участка кода. Зачастую они перерастают в спор о том, какое же решение работает больше стремительно. И в этой обстановки Почаще отменнее набросать простенький бенчмарк, чем вести длинные философские разговоры о продуктивности. К сожалению, дюже многие не умеют бенчмаркать верно, в итоге чего их тесты могут показать в корне неверные итоги. Следственно мне хотелось бы обсудить особенно значимые вещи, которые необходимо рассматривать при составлении грамотного бенчмарка на C#.

  • Release mode without debugging
    Одной из самых распространённых ошибок при тестах продуктивности является запуск программы в Debug mode. Итоги, полученные таким образом могут в тезисе не соответствовать реальности. Дело в том, что в Debug build компилятор C# добавляет уйма IL-команд, которые могут гораздо сказаться на продуктивности. Помимо того, запускать следует непременно без отладки (Ctrl F5 из студии, а ещё отменнее — из консоли). Если запустить приложение с отладкой (F5 из студии), то отладочный код также крепко попортит итоги вашего бенчмарка. Больше подробное изложение этой задачи дозволено обнаружить у Эрика Липперта.
  • Прогрев кеша процессора
    Запуск вашего теста должен осуществляться непременно на прогретом кеше. Для этого нужно перед замером времени запустить тест вхолостую несколько раз. Некоторые в порядке прогрева делают только один-два холостых запуска, но в действительности порой требуется 10-15 запусков, Дабы кеш подлинно прогрелся. Отменнее каждого греть кеш до тех пор, пока колебания замеров времени от запуска к запуску не станут поменьше некоторого небольшого процента. Итоги бенчмарка на непрогретом кеше могут быть дольше реальных в несколько десятков раз.
  • Запуск на одном процессоре
    Также следует помнить, что мы живём в многопроцессорном мире, а у всякого процессора есть свой кеш. Для того, Дабы принудить бенчмарк выполняться только на одном процессоре необходимо выставить соответствующую ProcessorAffinity-маску:

    Process.GetCurrentProcess().ProcessorAffinity = new IntPtr(1);
    
  • Stopwatch, а не DateTime
    Отличной практикой является мерить время работы программы через Stopwatch. Подробнее можете почитать у того же Эрика Липперта либо на dotnetperls.
  • Высокий приоритет
    Не забывайте, что помимо вашей программы на компьютере выполняются также десятки других приложений. Отменнее бы особенно «тяжёлые» из них отключить на время теста, а ещё отменнее задать в вашем приложений высокий приоритет для процесса и потока:

    Process.GetCurrentProcess().PriorityClass = ProcessPriorityClass.High;
    Thread.CurrentThread.Priority = ThreadPriority.Highest;
    
  • Сборка мусора
    Не забывайте про сборщик мусора, тот, что может неожиданно запуститься, когда его вовсе не ждёшь. И если сборка мусора объектов из нынешнего теста должна учитываться при замерах времени, то сборка мусора объектов из предыдущего теста нам совсем не необходима. Для этого отлично бы перед тестом вызвать GC.Collect(). А отменнее бы его вызывать два раза, Дабы все корневые объекты перешли во второе поколение (подробнее можете почитать здесь). Дождаться окончания выполнения всех финализаторов (если таковые имеются) тоже не помешает (в этом нам поможетGC.WaitForPendingFinalizers()).
  • Запуск целевого теста несколько раз
    Обособленный запуск теста может в силу различных обстоятельств (скажем, неожиданная активность иной программы) показать неправильные итоги. Следственно для обеспечения чистоты эксперимента не помешает вызвать целевой тест (теснее позже прогрева кеша) несколько раз, а после этого предпочесть средний итог. Также пригодно посмотреть на разброс значений на различных запусках для оценки степени доверия к итогам бенчмарка.

Я перечислил некоторые значимые моменты, которые нужно помнить при написании бенчмарка. Я люблю побенчмаркить, но всякий раз снова в всяком новом приложении обеспечивать чистоту эксперимента меня утомляет. Помимо того, хочется получить итоги теста в прекрасном виде, а возиться всякий раз с форматированием неохота. Следственно я написал простенький план BenchmarkDotNet (доступен на GitHub), тот, что в комфортном виде разрешает оценить продуктивность волнующих нас участков кода — довольно лишь описать целевые способы. Верю, данный план поможет иным C#-разработчиком верно оценить продуктивность их кода. Если же вы можете подсказать добавочные вещи, которые следует рассматривать для правильных замеров времени, то буду рад PullRequest-ам.

Источник: programmingmaster.ru
Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB