不久前有人问Is the ++ operator more efficient than a=a+1?。我之前认为我对此进行了分析,并且最初表示a = a + 1
和增量运算符++
之间没有区别。事实证明,a++
,++a
和a += 1
都编译为相同的字节码,但a = a + 1
执行不,如下所示:
public class SO_Test
{
public static void main(String[] args)
{
int a = 1;
a++;
a += 1;
++a;
}
}
输出:
示例:
public class SO_Test
{
public static void main(String[] args)
{
int a = 1;
a = a + 1;
a++;
a += 1;
++a;
}
}
输出:
简而言之,a = a + 1
发布iload_1
,iconst_1
,iadd
和istore_1
,而其他人只使用iinc
。
我试图理顺这一点,但我无法做到。在这种情况下,编译器 smart 是否足以优化字节码?这些是不同的有充分理由吗?这是由JIT处理的吗?除非我不正确地解释这一点,否则我似乎永远不应该使用a = a + 1
,我认为这肯定只是一种风格选择。
答案 0 :(得分:7)
流行的哲学是javac
故意选择不优化生成的代码,依赖于JIT编译器在运行时这样做。后者有更好的有关执行环境(硬件架构等)的信息,以及如何在运行时使用代码。
现在,我认为只要阅读字节码就可以得出关于性能的任何实际结论。关于过早优化的争论除外,如果你真的想知道是否存在差异,construct a micro-benchmark并亲眼看看。
答案 1 :(得分:1)
值得注意的是,这是特定于编译器的。我发现至少有一个eclipse版本编译x=x+1
的方式与x++
相同。此外,这仅与局部变量相关,因为字段没有类似的字节代码指令。它仅适用于int
类型的变量。因此字节码的影响相当有限。它最有可能改善常见的for(int i=start; i<limit; i++)
模式。在语言方面,它尤其适用于a[b()] ++
与a[b()] = a[b()] + 1
等等。