Вопрос с собеседования · Java

Какие ошибки чаще всего делают самодельный микробенчмарк бессмысленным?

SeniorJIT и производительность
Ещё спрашивают так:
  • Почему замеру через System.nanoTime в цикле нельзя верить?
  • Коллега замерил два варианта кода через System.nanoTime в цикле и сделал вывод о производительности. Почему такому замеру нельзя верить?
Коротко

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

  • Все три ошибки дают одинаково «впечатляющие» результаты
  • JMH: Blackhole, @State, прогрев и форки
  • Один прогон — не статистика

А ещё Профилировщик (async-profiler) часто полезнее микробенчмарка

Подробно

Все три ошибки приводят к одинаково впечатляющему результату: измеряемый код просто исчезает. JIT вправе удалить вычисление, результат которого никому не нужен, и свернуть выражение, вход которого известен заранее. Именно поэтому JMH предлагает Blackhole для потребления результата и аннотацию State для входных данных, которые компилятор не сможет счесть константами, а также сам управляет прогревом и итерациями. К этому добавляются менее очевидные факторы, которые JMH тоже учитывает: разброс между запусками JVM, влияние сборки мусора и профиль, накопленный предыдущими бенчмарками в том же процессе. Общий вывод для собеседования — измерять микропроизводительность вручную практически невозможно, и правильный ответ на вопрос «как вы это измеряли» звучит как JMH.

Что хотят услышать

  • Три классические ошибки и почему.
  • Как решает JMH.

Частые ошибки

  • Верить результатам замера через System.nanoTime без прогрева.
  • Игнорировать разброс между запусками и мерить один раз.

Проверьте себя

Несколько верных вариантов. Подумайте, потом откройте ответ.

Показать варианты и ответ
  • ✓Нет прогрева: измеряется интерпретируемый код
  • ✗Использование long вместо int для накопления результата: 64-битная арифметика заметно искажает замер
  • ✓Мёртвый код: результат не используется, и JIT выбрасывает вычисление
  • ✓Свёртка констант: вход известен заранее, и вычисление делается раз

Что спросят дальше

  • Зачем нужен Blackhole?
  • Почему один прогон JVM не даёт надёжного результата?
  • Что такое деоптимизация и почему она случается после долгой работы?
  • Когда микробенчмарк вообще не нужен?

Разбор темы

Связанные вопросы

Партнёр платформы

Разбор собеседования с sotto

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

Разбор собеседования