8

int a=a+1using和a++in之间有任何性能差异Java吗?

如果是这样,哪个更好,为什么?你能简单地解释一下我理解这一点吗?

4

6 回答 6

15

首先,Java 语言规范没有说明时间。但是假设我们使用的是典型的编译器,比如 Suns javac,我们会看到上面所有的例子(a++, ++a, a += 1, a = a + 1)都可以编译成类似的东西:

  • iinc指令,处理变量:

    iload_<variable>
    iinc <variable>, 1
    istore_<variable>
    
  • iadd指令,使用堆栈(这里使用变量1作为存储):

    iload_1
    iconst_1
    iadd
    istore_1
    

由编译器选择最好的编译方式。例如,它们之间没有区别。陈述之间不应该有任何区别——它们都表达了同样的东西——在数字上加一。

话虽如此,都可以使用 JITiinc将版本和iadd版本编译为快速且依赖于平台的东西,最后我会假设正常的运行时将两个版本编译成相同的汇编代码。


使用我的编译器,*jdk1.6.0_20*“增量”方法甚至使用相同的指令。

public class Test {
    public static void main(String[] args) {

        int a = 0;

        a = a + 1;
        a += 1;
        a++;
        ++a;
    }
}

这是反汇编:

Compiled from "Test.java"
public class Test extends java.lang.Object{
public Test();
  Code:
   0:   aload_0
   1:   invokespecial   #8; //Method java/lang/Object."<init>":()V
   4:   return

public static void main(java.lang.String[]);
  Code:
   0:   iconst_0
   1:   istore_1
   2:   iinc    1, 1   // a = a + 1;
   5:   iinc    1, 1   // a += 1;
   8:   iinc    1, 1   // a++;
   11:  iinc    1, 1   // ++a;
   14:  return

}
于 2012-02-15T11:27:36.853 回答
3

查看生成的字节码:

public static void main(String[] args) {
    int x = 1;
    int y = 1;
    int z = 1;
    int a = 1;
    int b = 1;
    x = x + 1;
    y++;
    ++z;
    a += 1;
    b += 2;
}

产生(使用javap -c classname

0:   iconst_1
1:   istore_1
2:   iconst_1
3:   istore_2
4:   iconst_1
5:   istore_3
6:   iconst_1
7:   istore  4
9:   iconst_1
10:  istore  5
12:  iload_1
13:  iconst_1
14:  iadd
15:  istore_1
16:  iinc    2, 1
19:  iinc    3, 1
22:  iinc    4, 1
25:  iinc    5, 2
28:  return

所以使用(jdk1.6.0_18):

x = x + 1

创建

12:  iload_1
13:  iconst_1
14:  iadd
15:  istore_1

然而

y++;
++z;
a += 1;

都导致

iinc

However, doing a rough performance test on my laptop resulted in next to no difference in the runtime between the two (sometimes ++x was quicker, sometimes x=x+1 was quicker), so I wouldn't worry about the performance implications.

于 2012-02-15T11:55:24.973 回答
2

不,不会有任何明显的差异。使用您认为最易读的内容(a++通常是 )。

代码优化的第一条规则:不要。

于 2012-02-15T11:25:21.253 回答
1

编译器应该优化,应该没有区别。但请记住,前缀增量运算符可能(取决于编译器)比后缀等效(在 C++ 和 C# 中)更快:

++aa++因为后缀运算符必须创建一个临时变量要快..考虑它们的实现:

字首:

a = a + 1;
return a;

后缀:

int tmp = a;
a = a + 1;
return tmp;
于 2012-02-15T11:27:31.400 回答
0

a++ 更快。它转换为汇编程序的 INC 命令。但我认为 JVM 会优化 a=a+1 所以你不需要关心这个。

于 2012-02-15T11:26:56.393 回答
0

是一样的,现在编译器优化不应该意识到这些东西,以提高你的性能检查其他更大的问题,比如 allocs :)

于 2012-02-15T11:27:07.447 回答