2016-04-08 2 views
1
int i = 0; 
i += 1; 
i = i + 1; 

В чем разница между этими двумя вариантами? Какие изменения в сроках выполнения? Какой из них самый мощный?Анализ разницы между i + = 1 и i = i + 1

+5

http://stackoverflow.com/questions/29179528/ii-i1-and-i-1-which-one-is-faster – Sahi

+0

Обязательно: выбор между 'i + = 1' и' i = i + 1 »не будет иметь абсолютно никакого заметного влияния на производительность программы. Программы медленны, потому что они делают такие вещи, как создание миллионов объектов, невероятно сложные вычисления или ожидание запросов сервера. – Radiodef

ответ

7

+ = подразумевается литье. Например, это будет компилировать:

int i = 0; 
i += 1L; 

И это не будет:

int i = 0; 
i = i + 1L; 

Пробовал собрать как фрагменты с моей jdk1.8.0_11 на Windows 8 и увидеть разницу байткодом ...

0: iconst_0 
1: istore_1 
2: iinc   1, 1 

для i += 1 версии, а также:

0: iconst_0 
1: istore_1 
2: iload_1 
3: iconst_1 
4: iadd 
5: istore_1 

для i = i + 1 версия.

Таким образом, вы можете получить различный байт-код (или, возможно, нет, см. Ответ @TDG) и другую производительность, но разница невелика по сравнению с другими накладными расходами, которые будут иметь ваши программы.

+0

Вы знаете, как получить этот код во внутреннем формате, например, для C# и ассемблера для C++? –

+0

@ h.o.m.a.n добавил к моему ответу –

+0

Вы уверены, что у вас разные бат-коды? Я получаю тот же байт-код для 'i + = 1',' i + = 1L' и 'i = i + 1' с jdk1.7.0_79. – TDG

2

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

i += 1; 

немного более эффективен, чем ..

i = i + 1; 

, так как адрес "я" только один раз обращались в "я + = 1". Это экономит вам одну операцию сборки, которая обычно не является большой проблемой, если ваши вычисления не могут быть выполнены с помощью многих итераций. Это приводит к сохранению инструкции сборки «mov».

+1

это правда? У процессоров есть операция «+ =»? –

+2

Вы действительно проверили Байт-код этих двух строк и видели какую-либо разницу? – TDG

+0

Согласен. Я думаю, даже если процессоры имеют операцию «+ =», компиляторы, вероятно, обнаружат «i = i + 1» и будут использовать операцию «+ =» –

0

i=i+1; она должна будет загрузить значение I, добавьте к нему, а затем сохранить результат обратно я

i+=1; добавьте к нему, а затем сохранить результат

РЕДАКТИРОВАТЬ 1 : некоторые говорят, что второй (i + = 1) работает быстрее, но если вы делаете разборку этого кода части, см. C++ (vs 2013), вы можете видеть, что они одинаковы. К сожалению, я не знаю, как это сделать в JAVA.

i = i + 1; 
00AF52C5 mov   eax,dword ptr [i] 
00AF52C8 add   eax,1 
00AF52CB mov   dword ptr [i],eax 
    i +=1; 
00AF52CE mov   eax,dword ptr [i] 
00AF52D1 add   eax,1 
00AF52D4 mov   dword ptr [i],eax 
+0

хорошо это верно, только если «добавить один к ней» «это еще одна операция. Что заставляет вас думать, что это так? и фактически, даже если это так, компиляторы, вероятно, обнаружат «i = i + 1» и будут использовать операцию «+ =» –

+0

@TDG, вы правы –

+0

@VicSeedoubleyew Я не знаю, как увидеть внутренний код в JAVA, но я знаю, как это сделать в C# (внутренний код IL) и C++ (ассемблер) –

1

Byte Code следующих двух "программы":

//first "program" 
int i = 0; 
i = i + 1; 

//second program 
int i = 0; 
i += 1; 

тот же:

0: iconst_0 
1: istore_1 
2: iinc   1, 1 
5: return 

И когда декомпиляция выше Byte Code мы получаем это -

int i = 0; 
++i; 

, поэтому не имеет значения, какой из них вы используете.

EDIT Вышеупомянутый был протестирован на jdk1.7.0_79 и Eclipse 3.8.2.

Смежные вопросы