Является ли бенчмаркинг секундомера приемлемым?


кто-нибудь когда-нибудь использует бенчмаркинг секундомера, или всегда должен использоваться инструмент производительности? Есть ли хорошие бесплатные инструменты для Java? Какие инструменты вы используете?

чтобы прояснить мои проблемы, бенчмаркинг секундомера подвержен ошибке из-за планирования операционной системы. При данном запуске вашей программы ОС может запланировать другой процесс (или несколько) в середине функции, которую вы синхронизируете. В Java все даже немного хуже, если вы пытаетесь время потоковое приложение, поскольку планировщик JVM бросает даже немного больше случайности в микс.

Как вы решаете планирование операционной системы при бенчмаркинге?

13 66

13 ответов:

секундомер бенчмаркинг отлично, если вы измеряете достаточно итераций, чтобы быть значимым. Как правило, мне требуется общее затраченное время в несколько секунд с одной цифрой. В противном случае ваши результаты легко значительно искажаются при планировании и других прерываниях O/S вашего процесса.

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

для профилирования работы я использовал jProfiler для ряда лет и нашли его очень хорошим. Я недавно просмотрел YourKit, который кажется отличным от веб-сайта, но я не использовал его вообще, лично.

чтобы ответить на вопрос о прерываниях планирования, я считаю, что выполнение повторных запусков до тех пор, пока не будет достигнута согласованность/наблюдаемые работы на практике, чтобы отсеять аномальные результаты от планирования процесса. Я также считаю, что планирование потоков не имеет практического влияния для запусков от 5 до 30 секунд. Наконец, после прохождения нескольких секунд пороговое планирование имеет, по моему опыту, незначительное влияние на результаты - я считаю, что 5-секундный запуск последовательно усредняет то же самое, что и 5-минутный запуск для времени/итерации.

вы также можете рассмотреть возможность предварительного запуска тестируемого кода около 10 000 раз, чтобы "разогреть" JIT, в зависимости от того, сколько раз вы ожидаете, что тестируемый код будет выполняться с течением времени в реальной жизни.

Он полностью действителен до тех пор, пока вы измеряете достаточно большие интервалы времени. Я бы выполнил 20-30 запусков того, что вы собираетесь протестировать, так что общее затраченное время составляет более 1 секунды. Я заметил, что расчеты времени основаны на системе.currentTimeMillis (), как правило, либо 0 мс, либо ~30 мс; я не думаю, что вы можете получить что-то более точное, чем это. Вы можете попробовать систему.nanoTime () если вам действительно нужно измерить небольшой интервал времени:

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

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

когда вы хотите на самом деле исправить проблемы, однако, профилировщик может быть очень полезно.

секундомер-это на самом деле лучший тест!

Реальное время отклика конечного пользователя-это время, которое действительно имеет значение.

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

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

вам нужно проверить реалистичное количество итераций, так как вы получите разные ответы в зависимости от того, как вы проверяете время. Если вы выполняете операцию только один раз, это может ввести в заблуждение, чтобы взять среднее значение многих итераций. Если вы хотите знать время, которое требуется после прогрева JVM, вы можете запустить много (например, 10 000) итераций, которые не включены в тайминги.

Я также предлагаю вам использовать систему.nanoTime (), а его гораздо более точным. Если ваше время испытания вокруг 10 микро-секунд или меньше, вы не хотите называть это слишком часто, или это может изменить ваш результат. (например, если я тестирую, скажем, 5 секунд, и я хочу знать, когда это произойдет, я получаю только nanoTime каждые 1000 итераций, если я знаю, что итерация очень быстрая)

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

сегодня я запустил программу, которая искала и собирала информацию из кучи файлов dBase, для запуска потребовалось чуть более часа. Я взглянул на код, сделал обоснованное предположение о том, что такое узкое место, сделал небольшое улучшение алгоритма и повторно запустил программу, на этот раз она завершилась за 2,5 минуты. Мне не нужно было никаких причудливых инструментов профилирования или эталонных наборов, чтобы сказать мне, что новая версия была значительным улучшением. Если мне нужно было дополнительно оптимизировать время работы, я возможно, пришлось бы провести более сложный анализ, но в этом не было необходимости. Я считаю, что такого рода "бенчмаркинг секундомера" является приемлемым решением в целом ряде случаев, и обращение к более продвинутым инструментам на самом деле было бы более трудоемким в этих случаях.

В конце концов, это, вероятно, вторая по популярности форма бенчмаркинга, сразу после "бенчмаркинга без часов"-где мы говорим: "эта деятельность кажется медленной, это кажется быстрым."

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

Я думаю, что ключевым вопросом является сложность и продолжительность операции.

Я иногда даже использую физические измерения секундомера, чтобы увидеть, занимает ли что-то минуты, часы, дни или даже недели для вычисления (я работаю с приложением, где время выполнения по порядку нескольких дней не является неслыханным, даже если секунды и минуты являются наиболее распространенными промежутками времени).

тем не менее, автоматизация обеспечивается за счет вызовов любого вида системы часов на компьютере, как и вызов Java millis, упомянутый в связанной статье, явно превосходит ручное наблюдение за тем, как долго что-то работает.

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

как вы решаете планирование операционной системы при бенчмаркинге?

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

нет смысла говорить, что моя программа была бы быстрее, если бы только у меня не было ОС.

если вы используете Linux, вы можете использовать такие инструменты, как numactl,chrt и taskset to контролируйте, как используются процессоры и планирование.

Я не думаю, что бенчмаркинг секундомера слишком ужасен, но если вы можете попасть на машину Solaris или OS X, вы должны проверить DTrace. Я использовал его, чтобы получить большую информацию о времени в моих приложениях.

Я всегда использую секундомер бенчмаркинга, как это гораздо проще. Результаты не должны быть очень точными для меня, хотя. Если вам нужны точные результаты, то вы не должны использовать секундомер бенчмаркинга.

Я делаю это все время. Я бы предпочел использовать профилировщик, но поставщик доменного языка, с которым я работаю, не предоставляет его.