Is ++x more efficient than x++ in Java?

无人久伴 提交于 2019-11-27 15:02:41
zneak

It's not more efficient in Java. It can be more efficient in languages where the increment/decrement operators can be overloaded, but otherwise the performance is exactly the same.

The difference between x++ and ++x is that x++ returns the value of x before it was incremented, and ++x returns the value of x after it was incremented. In terms of code generation, both make up for the exact same number of instructions, at least when you can use either interchangeably (if you can't use them interchangeably, you shouldn't be worrying about which one is faster, you should be picking the one you need). The only difference is where the increment instruction is placed.

In C++, classes can overload both the prefix (++x) and postfix (x++) operators. When dealing with types that overload them, it is almost universally faster to use the prefix operator because the semantics of the postfix operator will return a copy of the object as it was before the increment, even when you wouldn't use it, while the prefix operator can simply return a reference to the modified object (and God knows C++ developers prefer to return references rather than copies). This could be a reason to consider ++x superior to x++: if you gain the habit of using ++x you could save yourself some slight performance trouble when/if you switch to C++. But in the context of Java only, both are absolutely equivalent.

Much like pst in the comments above, I never use the return value of x++ or ++x, and if you never do either, you should probably just stick to the one you prefer.

Out of curiosity, you can check the generated bytecode.

This program:

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
}

generates the following bytecode:

  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

So you can see that pre and post fix operators are strictly identical from a bytecode perspective (apart from the order of the operations).

If and when the JIT compiles that part of your code, all bets are off. For example, the code above, as is, could be compiled as a no-op because it has no side effects.

The truth of the matter is that *x++ was faster than *++x in C on a PDP-11, and maybe a VAX, because it compiled to a single instruction (autoincrement register deferred). Similarly *--x was faster than *x--. Using either form without the dereference would only be faster in one case rather than the other if the compiler still generated that instruction, which would have been wasteful because the dereference would still have occurred.

Those days are long gone.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!