Что быстрее: null == myObject или myObject == null?

Как в Java, так и в .Net я слышал, что использование null first if (null == myObject) более производительно, чем использование объекта first if (myObject == null). Хотя я думаю, что это, вероятно, правда, я не уверен и хотел бы знать от пользователей SO. Лично я считаю, что будет лучше, если на объект будет сделана ссылка в первую очередь, но если есть какой-либо выигрыш в производительности за счет использования сначала null, я выберу это вместо этого.


person johntrepreneur    schedule 14.03.2013    source источник
comment
Крайне маловероятно, что разница, если она вообще есть, имеет значение.   -  person millimoose    schedule 15.03.2013
comment
В Java они оба не компилируются, если вы по ошибке поставили =.   -  person QuentinUK    schedule 15.03.2013
comment
@QuentinUK, если вы не сравните логическое   -  person Thorbjørn Ravn Andersen    schedule 15.03.2013
comment
Теперь я вижу, что на самом деле это всего лишь результат того, как программисты на C используют код, чтобы избежать ошибок, поскольку эта практика кодирования была предложена мне бывшим программистом на C.   -  person johntrepreneur    schedule 15.03.2013
comment
@ Thorbjørn Ravn Andersen в этом случае можно использовать первое, чтобы избежать случайных ошибок, точно так же, как в C принято ставить константу слева.   -  person QuentinUK    schedule 15.03.2013
comment
@johntrepreneur Java была намеренно разработана так, чтобы напоминать C. Ссылки на Java работают совершенно иначе, чем указатели C, поэтому привычки C для указателей не переносятся на ссылки.   -  person Thorbjørn Ravn Andersen    schedule 15.03.2013
comment
@ ThorbjørnRavnAndersen, верно, так что это просто старая привычка (некоторыми) и не имеет добавленной стоимости в Java.   -  person johntrepreneur    schedule 15.03.2013


Ответы (4)


Они точно такие же. Если бы была разница, любой компилятор сделал бы подкачку, так как нет абсолютно никакой функциональной разницы.

person Denys Séguret    schedule 14.03.2013
comment
Я знаю, что функционально они такие же, но мне было интересно узнать о производительности. - person johntrepreneur; 15.03.2013

Удивительно, но в Java они компилируются по-разному:

if (myObject == null);
if (null == myObject);

компилируется в

 8 aload_1
 9 ifnonnull 12 (+3)
12 aconst_null
13 aload_1
14 if_acmpne 17 (+3)

(Это было скомпилировано с использованием javac 1.6.0_24.)

Помещение ссылки на объект сначала приводит к двум инструкциям, а указание null первым приводит к трем инструкциям. Исходя из этого, if (myObject == null) может быть быстрее.

Однако, как указывает Торбьёрн Равн Андерсен, при использовании JIT-компилятора количество инструкций байт-кода не имеет большого значения, поскольку байт-код в любом случае будет преобразован в собственный код перед выполнением. И даже если есть разница в производительности, я сомневаюсь, что ее можно будет измерить.

person matts    schedule 14.03.2013
comment
Вы не можете определить скорость выполнения по количеству байтовых кодов, если ваша JVM использует JIT-компилятор. - person Thorbjørn Ravn Andersen; 15.03.2013
comment
+1 При упоминании байт-кода. По той же причине объединение строк менее эффективно с оператором +, чем с StringBuilder. - person Bart; 15.03.2013
comment
@ ThorbjørnRavnAndersen Ах, хорошее замечание. Я откорректирую свой ответ. - person matts; 15.03.2013
comment
@matts вы заявили И даже если есть разница в производительности, я сомневаюсь, что ее можно будет измерить. Разве более крупные объекты не занимали бы больше времени, если бы он оценивал весь объект в отличие от небольшого объекта, просто чтобы увидеть, является ли его значение null? Я бы подумал, что он откажется от проверки всего объекта, если он знает, что ему просто нужно проверить, является ли его значение null. - person johntrepreneur; 15.03.2013
comment
@johntrepreneur Ну, я не эксперт, но не думаю, что размер объекта имеет значение. При использовании с объектами оператор == сравнивает ссылки на объекты, аналогично указателям в других языках. Фактически он не оценивает ценность объекта. Кроме того, сам объект не может быть нулевым, только переменная (которая может указывать на объект) может быть нулевой. - person matts; 15.03.2013
comment
В C # у меня было то же самое до того, как я добавил фальшивую операцию между двумя тестами. Без этой фальшивой операции генерируемый байт-код оптимизируется для повторного использования нулевого значения, уже находящегося в регистрах. - person Steve; 15.03.2013
comment
@matts ахх, ты прав, хороший момент (+1). Думаю, я смешиваю разные языки, на которых его использую. В Java - да; в C # == перегружен, чтобы разрешить проверку равенства, хотя я думаю, что это просто синтаксический сахар, поэтому он, вероятно, такой же, как Java. Однако в javascript вы можете использовать оператор == для проверки равенства, хотя теперь я выхожу за рамки моего исходного вопроса, поскольку я не просил этот язык, но мне все еще любопытно, как можно применить эту практику там тоже. - person johntrepreneur; 15.03.2013
comment
@matts, чтобы подвести итог, если оператор == проверяет равенство, как в javascript, тогда он будет оценивать содержимое объектов, и обход большего объекта займет больше времени, если он не знает заранее, он просто ищет null ( т.е. ноль слева). - person johntrepreneur; 15.03.2013
comment
@johntrepreneur в Java оператор == не перегружен для сравнения содержимого объектов на предмет равенства. Для этого нужно использовать метод equals. При использовании с двумя отдельными объектами == оценивается как false, даже если они имеют одинаковое содержимое. Например, new String("test") == new String("test") должно оцениваться как false, хотя new String("test").equals(new String("test")) будет оцениваться как true. Не уверен, что это ответ на ваш вопрос - person matts; 15.03.2013
comment
@matts спасибо, но нет, это основы Java 101. Нет, мой вопрос касался Javascript, где вы можете проверить равенство with ==, и как это работает с более крупными объектами? Более конкретно, если объект находится слева от условного (в Javascript) if (myObject == null), будет ли он сначала читать весь объект, а затем выполнять нулевую проверку? вместо того, чтобы if (null = myObject) знать, что ему просто нужно знать, является ли он нулевым, и закоротить чтение объекта, как только он поймет, что он не равен нулю. - person johntrepreneur; 15.03.2013
comment
@johntrepreneur Ох, извини, что я неправильно понял; Я понятия не имею о JavaScript, но я думаю null - это константа, и я бы предположил, что, поскольку многие движки JavaScript в наши дни также используют JIT, они оптимизировали бы полный сравнение объектов. - person matts; 15.03.2013

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

person Louis Wasserman    schedule 14.03.2013

Не могу сказать о Java, но буду очень удивлен, если там все будет иначе.
В примере C # я пишу

void Main()
{
    object o = new object();

    if(null == o)
        Console.WriteLine("o is null");

    // to force a reload of the registers
    o = new object();

    if(o == null)
        Console.WriteLine("o is null");
}

результирующий код IL

IL_0000:  newobj      System.Object..ctor
IL_0005:  stloc.0     // o
IL_0006:  ldloc.0     // o
IL_0007:  brtrue.s    IL_0013
IL_0009:  ldstr       "o is null"
IL_000E:  call        System.Console.WriteLine
IL_0013:  newobj      System.Object..ctor
IL_0018:  stloc.0     // o
IL_0019:  ldloc.0     // o
IL_001A:  brtrue.s    IL_0026
IL_001C:  ldstr       "o is null"
IL_0021:  call        System.Console.WriteLine

ВООБЩЕ НЕТ РАЗНИЦЫ

person Steve    schedule 14.03.2013