Простой микро-тест с JMH

Вдохновленный еще одним вопросом о переполнении стека, я написал микро-тест, чтобы проверить, что является более эффективным:

  • условно проверяя делитель нуля или
  • ловить и обрабатывать ArithmeticException

Ниже мой код:

@State(Scope.Thread)
@BenchmarkMode(Mode.AverageTime)
@OutputTimeUnit(TimeUnit.NANOSECONDS)
public class MyBenchmark {

    private int a = 10;
    // a little bit less obvious than int b = 0;
    private int b = (int) Math.floor(Math.random());

    @Benchmark
    public float conditional() {
        if (b == 0) {
            return 0;
        } else {
            return a / b;
        }
    }

    @Benchmark
    public float exceptional() {
        try {
            return a / b;
        } catch (ArithmeticException aex) {
            return 0;
        }
    }
}

Я совершенно новичок в JMH и не уверен, что код в порядке.

Мой тест верен? Вы видите какие-либо ошибки?

Сторона не: пожалуйста, не предлагайте спрашивать на https://codereview.stackexchange.com/. Для Codereview код должен уже работать как задумано. Я не уверен, что этот тест работает как задумано.

1 ответ

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

Я бы сделал три варианта каждого метода:

  1. со случайным массивом с перемешанными нулями и параметризацией эталона с индексом в этом массиве.
  2. со случайным массивом ненулевых чисел
  3. со всеми 0

Это должно дать вам хорошее представление об общей производительности, включая прогнозирование ветвлений. Для пункта (1) также может быть интересно поиграть с отношением 0 к ненулевым.

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

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

Другие вопросы по тегам