Допустим ли сравнительный анализ секундомера? - PullRequest
71 голосов
/ 04 января 2009

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

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

Как вы относитесь к планированию операционной системы при тестировании?

Ответы [ 13 ]

48 голосов
/ 04 января 2009

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

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

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

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

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

6 голосов
/ 04 января 2009

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

5 голосов
/ 06 января 2009

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

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

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

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

5 голосов
/ 04 января 2009

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

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

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

4 голосов
/ 24 января 2009

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

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

2 голосов
/ 24 января 2009

Как вы относитесь к планированию операционной системы при тестировании?

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

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

Если вы используете Linux, вы можете использовать такие инструменты, как numactl, chrt и taskset, чтобы контролировать использование процессоров и планирование.

2 голосов
/ 04 января 2009

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

1 голос
/ 04 января 2009

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

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

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

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

1 голос
/ 04 января 2009

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

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

1 голос
/ 04 января 2009

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

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

...