Что является различием в производительности, если таковые имеются, между если (! нечто) и если (нечто == ложь) в Java?

Логически, if(!foo) и if(foo == false) эквивалентны. Как они представлены в Java? Есть ли какое-либо различие между двумя после компиляции, или в байт-коде или в производительности? Я не мог найти ответ в JLS и поиск поднятого много результатов о = по сравнению с == опечатки и ==/equals () поведение. (В этом случае символы препятствовали моему поиску; для будущих искателей, оператора отрицания, равняется лжи, равной лжи, не условию).

Препятствовать дебатам CW: этот вопрос НЕ спрашивает, который предпочитают различные люди или который считают лучшим стилем. Я интересуюсь различиями в реализации языка, таким образом, существует корректный ответ. Related-but-not-quite-a-dupe: Различие, между в то время как (x = ложь) и в то время как (! x) в Java?

Править:

Общее согласие, кажется, что хороший компилятор должен оптимизировать их к тому же самому. Это имеет смысл и - то, что я подозревал, но - для выяснения ЕЩЕ У БОЛЬШЕГО академического вопроса - что поведение на самом деле передано под мандат где-нибудь, или это - "просто" разумная вещь сделать?

15
задан Community 23 May 2017 в 11:55
поделиться

8 ответов

JLS укажет требуемое поведение утверждений. Однако как они реализуются, представляет собой деталь реализации компилятора и JVM.

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

Кроме того, лучший способ ответить на это, это проверить для себя, используя javap :

  1. Компиляция A Test.java с следующим содержанием:

     класс  Тест {
      пустота равно (логическом е) {
      если (f == false) {}
      }
      недействительно нет (Boolean f) {
      Если (! F) {}
      }
     }
     $ Javac test.java
     
  2. Сделайте это:

     TEST JAVAP -C
    Скомпилирован из "test.java"
    Классовый тест расширяет Java.lang.Object {
    Тест();
      Код:
      0: Aload_0.
      1: Invoxecial # 1;  // Метод Java / Lang / Object. "" :() v
      4: возврат
    
    пустота равно (логическом);
      Код:
      0: Iload_1.
      1: ifne 4
      4: возврат
    
    пустота нет (логический);
      Код:
      0: Iload_1.
      1: ifne 4
      4: возврат
    
     }
     

Обновление: Отвечая на вопрос о «академическом» вопросе. Как уже упоминалось выше, JLS касается только поведением. В стандарте нет ничего, что на самом деле указывает, как оно должно быть реализовано (ну, JVMS предоставляет много рекомендаций).

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

44
ответ дан 1 December 2019 в 00:08
поделиться

ОК, более полный ответ:

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

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

0
ответ дан 1 December 2019 в 00:08
поделиться

Компилятор должен разрешить к тому же коду внутренне, Так что нет разницы.

12
ответ дан 1 December 2019 в 00:08
поделиться

JLS говорит, что

выражение в Если блок оценивается, то результат этого выражения сравнивается с True

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

Но в этом случае я ожидаю, что JIT создает тот же байт-код для обоих выражений.

0
ответ дан 1 December 2019 в 00:08
поделиться

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

0
ответ дан 1 December 2019 в 00:08
поделиться

Я задавал аналогичный вопрос Что касается C ++ / VS2008.

VS2008 C ++ Компилятор оптимизирует следующее, если оператор?

Во избежание = vs == Typos в C ++, вы, как правило, пишут

if (NULL == ptr) { ... }
if (false == boo) { ... }
if (20 == num) { ... }

и т. Д.

Это немного менее доступно, пока вы не привыкнете к нему.

0
ответ дан 1 December 2019 в 00:08
поделиться

Думаешь о микро оптимизациях практически в любых случаях пустая трата времени и приводит к мышлению неправильно ...

0
ответ дан 1 December 2019 в 00:08
поделиться

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

0
ответ дан 1 December 2019 в 00:08
поделиться
Другие вопросы по тегам:

Похожие вопросы: