++x более эффективен, чем x++ в Java?
На уроке программирования профессор учил нас x++
а также ++x
с х является целым числом.
Он сказал, что в сценарии мы можем просто x++
или же ++x
, ++x
является более эффективным (немного, но, теоретически, тем не менее, более эффективным).
Но я забыл почему. Кто-нибудь знает? Это было с Java.
3 ответа
Это не более эффективно в Java. Это может быть более эффективным в языках, где операторы увеличения / уменьшения могут быть перегружены, но в остальном производительность точно такая же.
Разница между x++
а также ++x
в том, что x++
возвращает значение x
прежде чем он был увеличен, и ++x
возвращает значение x
после того, как он был увеличен. С точки зрения генерации кода, оба компенсируют одинаковое количество инструкций, по крайней мере, когда вы можете использовать оба взаимозаменяемо (если вы не можете использовать их взаимозаменяемо, вы не должны беспокоиться о том, какая из них быстрее, вы должны быть выбираю тот, который вам нужен). Единственная разница в том, где находится инструкция приращения.
В C++ классы могут перегружать оба префикса (++x
) и постфикс (x++
) операторы. При работе с типами, которые перегружают их, почти всегда быстрее использовать префиксный оператор, потому что семантика постфиксного оператора будет возвращать копию объекта, как это было до приращения, даже если вы не будете использовать его, в то время как Префиксный оператор может просто возвращать ссылку на измененный объект (и Бог знает, что разработчики на C++ предпочитают возвращать ссылки, а не копии). Это может быть причиной для рассмотрения ++x
превосходит x++
: если вы приобрели привычку использовать ++x
Вы можете избежать некоторых проблем с производительностью, если / если вы переключитесь на C++. Но только в контексте Java оба абсолютно эквивалентны.
Как и pst в комментариях выше, я никогда не использую возвращаемое значение x++
или же ++x
и если вы никогда этого не сделаете, вам, вероятно, следует просто придерживаться того, который вы предпочитаете.
Из любопытства вы можете проверить сгенерированный байт-код.
Эта программа:
public static void main(String args[]) {
int i = 1; //bytecode 0, 1
i++; //bytecode 2
++i; //bytecode 5
int a = ++i; //bytecode 8, 11, 12
int b = i++; //bytecode 13, 14, 17
}
генерирует следующий байт-код:
public static void main(java.lang.String[]);
Code:
0: iconst_1
1: istore_1
2: iinc 1, 1
5: iinc 1, 1
8: iinc 1, 1
11: iload_1
12: istore_2
13: iload_1
14: iinc 1, 1
17: istore_3
18: return
Таким образом, вы можете видеть, что операторы до и после исправления строго идентичны с точки зрения байт-кода (кроме порядка операций).
Если и когда JIT компилирует эту часть вашего кода, все ставки отключены. Например, приведенный выше код может быть скомпилирован как неиспользуемый, поскольку он не имеет побочных эффектов.
Правда в том, что *x++
был быстрее чем *++x
в C на PDP-11 и, возможно, VAX, потому что он скомпилирован в одну инструкцию (регистр автоинкремента отложен). так же *--x
был быстрее чем *x--
, Использование любой формы без разыменования будет быстрее только в одном случае, а не в другом, если компилятор все еще сгенерирует эту инструкцию, что было бы бесполезным, потому что разыменование все равно произошло бы.
Эти времена давно прошли.