Подтвердить что ты не робот

Является ли Math.max(a, b) или (a> b)? A: b быстрее в Java?

Какой из них быстрее в Java и почему?

  • Math.max(a,b)
  • (a>b)?a:b

(Это было задано в интервью.)

4b9b3361

Ответ 1

Math.max(a, b) является статической функцией (что означает отсутствие служебных ресурсов виртуального вызова) и, вероятно, будет встроено JVM в те же инструкции, что и (a > b) ? a : b.

Ответ 2

Здесь является openjdk код для Math.max() в Java:

public static int max(int a, int b) {
    return (a >= b) ? a : b;
}

Таким образом, код, вероятно, будет (почти) точно такой же скоростью.

(Если честно, если вы беспокоитесь об улучшении скорости на таком низком уровне, у вас, вероятно, гораздо больше проблем в вашем коде.)

Ответ 3

Вопросы производительности всегда вызывают тест, прежде чем вы сможете начать спекулировать:

public static void maxtest()
{
    int res = 0;
    for( int idx = 0; --idx != 0; )
        // res = ( res > idx ) ? res : idx;
        res = Math.max( res, idx );
    System.out.println( "res: " + res );
}

Это работает на моей машине 6 секунд с Math.max() и 3.2 секунды с ?: на последнем сервере 1.6.1 x64 Sun JVM. Итак, ?: на самом деле быстрее. Вопреки всем надеждам, которые мы хотели бы включить в JIT, которые действительно стали потрясающими к тому времени, когда они все еще не поймают все.

EDIT: Из любопытства я также пробовал этот код с 32-битным клиентом JVM 1.6.1 на том же компьютере и с этими двумя версиями запускался за 7 секунд! Таким образом, вероятно, это не вызов метода, который не встраивается, но сервер JIT, похоже, может сделать некоторые дополнительные оптимизации для этого конкретного тестового примера, что он не может обнаружить, когда есть вызов метода.

Ответ 4

Я был на приемной стороне этого типа вопросов, и они обычно больше о том, как вы отвечаете на вопрос, чем то, что "правильный" ответ.

Ответ 5

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

Ответ 6

В исходном вопросе не указывается тип аргументов. Это имеет значение, потому что определение max (и min) для аргументов с плавающей запятой является более сложным. Для с плавающей запятой (double или float) метод Math.max, вероятно, будет медленнее, но также может возвращать другой результат, если один из аргументов - NaN.

Ответ 7

Не полагайтесь на спекуляцию. Вместо этого benchmark ваш конкретный пример использования.

Некоторые легко забытые детали во многих других ответах:

Пока вы видите источник Java Math.max, на самом деле это не всегда то, что будет использоваться. Этот метод имеет внутреннюю версию почти в каждой JRE. См. исходный код Hotspot в JDK7, vmSymbols.hpp для списка таких встроенных функций.

Насколько я могу судить, Hotspot попытается выполнить ряд оптимизаций, когда увидит оператор max или min; в частности для оптимизации, например, arraycopy. Кроме того, он фактически оптимизирует Math.max(same, same).

В других случаях, однако, это может не сильно оптимизировать; (a<=b)?a:b может быть на самом деле быстрее. Я немного сравнился, и я часто обнаружил, что это быстрее. Но YMMV, и это определенно зависит от контекста, если Hotspot может оптимизировать один лучше или другой. Он также будет отличаться от версии с горячей точкой до версии hotspot...

Ответ 8

Не то же самое. Когда вы пишете (a > b) ? a : b, у вас нет дополнительного вызова функции, поэтому он будет быстрее. Это эквивалент вложения в С++. Но это не будет иметь никакого значения в реальной жизни. Math.max(a,b) более читабельна, поэтому я буду использовать ее.