Java Academy · Урок

Написание измерения производительности

@Benchmark и режимы

Урок 2 из 413 шагов

«Написание измерения производительности» — бесплатный урок Java Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Java Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Java Academy содержит 4 уроков всего.

Написание микротеста

Микротест JMH — это обычный метод с аннотацией @Benchmark внутри обычного класса. Обработчик аннотаций JMH создаёт вокруг него необходимый каркас. В этом уроке рассматриваются аннотации, определяющие, что и как Вы измеряете.

Аннотация @Benchmark

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

Минимальный класс микротеста

Так выглядит структура микротеста. Импорт выполняется с помощью org.openjdk.jmh.annotations.*. Поскольку JMH отсутствует в пути к классам этого средства выполнения, приведённый пример носит только иллюстративный характер.

import org.openjdk.jmh.annotations.Benchmark;

public class StringBench {
    @Benchmark
    public String concat() {
        return "foo" + System.nanoTime();
    }
}

Режимы микротестирования

@BenchmarkMode определяет, что будет указано в отчёте:

  • Пропускная способность — количество операций за единицу времени (больше — лучше).
  • AverageTime — время на одну операцию (меньше — лучше).
  • SampleTime — распределение времени (процентили).
  • SingleShotTime — один вызов, подходит для измерения холодного запуска.
import org.openjdk.jmh.annotations.*;

public class Bench {
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    public int work() {
        return 2 + 2;
    }
}

Выбор единиц вывода

@OutputTimeUnit задаёт единицу времени для отчёта, чтобы числа было удобно читать. Для быстрой операции подходят наносекунды, а для медленной — миллисекунды.

import java.util.concurrent.TimeUnit;
import org.openjdk.jmh.annotations.*;

public class Bench {
    @Benchmark
    @BenchmarkMode(Mode.AverageTime)
    @OutputTimeUnit(TimeUnit.NANOSECONDS)
    public int work() {
        return 42;
    }
}

Возврат результатов

Всегда возвращайте результат работы. JMH автоматически передаёт возвращаемые значения в поглотитель, предотвращая устранение мёртвого кода. Микротест с типом void, который вычисляет результат и отбрасывает его, — классическая ошибка.

Значения аннотаций по умолчанию

Аннотации можно размещать на методе или на всём классе. Аннотации уровня класса применяются к каждому @Benchmark в этом классе, что помогает не повторять настройки при наличии нескольких связанных микротестов.

Запуск в отдельных JVM

@Fork(n) запускает микротест в n новых процессах JVM. Отдельные запуски изолируют каждый результат от профилей JIT, накопленных предыдущими микротестами, и повышают воспроизводимость. По умолчанию используется один запуск.

import org.openjdk.jmh.annotations.*;

@Fork(2)
public class Bench {
    @Benchmark
    public long now() {
        return System.nanoTime();
    }
}

Запуск средства выполнения

Микротесты запускаются через main, который настраивает объект Options и объект Runner, либо через созданный исполняемый JAR. Регулярное выражение include(...) выбирает, какие микротесты запускать.

import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.options.*;

public class Launcher {
    public static void main(String[] args) throws Exception {
        Options opt = new OptionsBuilder()
            .include("Bench")
            .build();
        new Runner(opt).run();
    }
}

Чтение вывода

JMH выводит таблицу с именем микротеста, режимом, количеством выборок, результатом, погрешностью результата и единицами измерения, например: Bench.work avgt 25 3.142 +/- 0.011 ns/op. Обозначение +/- — это доверительный интервал.

Сосредоточьтесь на одной задаче

Каждый микротест должен измерять что-то одно. Смешивание подготовки, ввода-вывода и проверяемой операции делает результат неоднозначным. Перенесите подготовку в методы @Setup (они рассматриваются вместе с состоянием), чтобы измерять только горячий участок кода.

Быстрая проверка

Проверьте, насколько хорошо Вы понимаете написание микротестов.

Итоги

Вы научились писать микротест JMH:

  • Помечайте метод аннотацией @Benchmark и возвращайте результат.
  • @BenchmarkMode выбирает Пропускную способность, AverageTime, SampleTime или SingleShotTime.
  • @OutputTimeUnit задаёт удобные для чтения единицы, а @Fork изолирует запуски в новых JVM.
  • Запускайте микротест с помощью средства выполнения и параметров либо созданного JAR.
  • Сосредотачивайте каждый микротест на одном горячем участке кода.
Можно начать бесплатно

Изучай Java с ИИ-репетитором — бесплатно

Пиши и запускай код прямо в браузере, получай мгновенную помощь от ИИ-репетитора 24/7 и продолжи учиться на сайте или в приложении.

Курсы
104
Уроки
374

Часто задаваемые вопросы

Урок «Написание измерения производительности» бесплатный?

Да — полный текст урока «Написание измерения производительности» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Java Academy, подпишись на CoddyKit PRO. Курс Java Academy содержит 4 уроков всего.

Чему я научусь в уроке «Написание измерения производительности»?

@Benchmark и режимы Ты практикуешь Java Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Java Academy?

Предыдущий опыт не требуется. Java Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Написание измерения производительности»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Java Academy?

Да. Каждый урок Java Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Зачем нужен JMH
  2. Написание измерения производительности
  3. Прогрев и итерации
  4. Предотвращение удаления неиспользуемого кода
← Назад к Java Academy