16

在编程课上,教授教我们关于x++++x,其中 x 是一个整数。

他说,在这种情况下,我们可以只使用x++or ++x++x效率更高(但在理论上,仍然更有效)。

但我忘记了为什么。有谁知道?这是Java。

4

3 回答 3

25

它在 Java 中效率并不高。在可以重载递增/递减运算符的语言中,它可能更有效,但除此之外性能完全相同。

x++和之间的区别在于++x返回x++递增x 之前的值,并++x返回递增x之后的值。在代码生成方面,两者都弥补了完全相同数量的指令,至少当你可以互换使用它们时(如果你不能互换使用它们,你不应该担心哪个更快,你应该选择你需要的)。唯一的区别是增量指令的放置位置。

在 C++ 中,类可以重载前缀 ( ++x) 和后缀 ( x++) 运算符。在处理重载它们的类型时,使用前缀运算符几乎普遍更快,因为后缀运算符的语义将返回对象的副本,就像它在增量之前一样,即使您不会使用它,而前缀运算符可以简单地返回对修改对象的引用(天知道 C++ 开发人员更喜欢返回引用而不是副本)。这可能是考虑++x优于的原因x++:如果您养成使用的习惯,++x 当/如果您切换到 C++ 时,您可以为自己节省一些轻微的性能问题。但仅在 Java 的上下文中,两者是绝对等价的。

就像上面评论中的pstx++一样,我从不使用or的返回值++x,如果你从不这样做,你可能应该坚持你喜欢的那个。

于 2012-09-12T22:02:23.877 回答
16

出于好奇,您可以检查生成的字节码。

这个程序:

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

所以你可以看到,从字节码的角度来看,prefix 和 postfix 运算符是完全相同的(除了操作的顺序)。

如果当 JIT 编译你的那部分代码时,所有的赌注都没有了。例如,上面的代码可以按原样编译为无操作,因为它没有副作用。

于 2012-09-12T22:46:39.100 回答
4

事情的真相是,它*x++PDP-11上的*++x C更快,也许是 VAX,因为它编译为一条指令(延迟自动增量寄存器)。同样比 快。如果编译器仍然生成该指令,那么使用没有取消引用的任何一种形式只会在一种情况下比另一种更快,这将是浪费的,因为仍然会发生取消引用。*--x*x--

那些日子已经一去不回。

于 2012-09-12T23:29:21.587 回答