我有很长一段时间都有同样的问题。所以我测试了一个更简单的代码。
结论:对于这种情况,没有性能差异。
循环外部的情况
int intermediateResult;
for(int i=0; i < 1000; i++){
intermediateResult = i+2;
System.out.println(intermediateResult);
}
循环内部情况
for(int i=0; i < 1000; i++){
int intermediateResult = i+2;
System.out.println(intermediateResult);
}
我在IntelliJ的反编译器上检查了编译文件,在两种情况下,我得到了相同的Test.class
for(int i = 0; i < 1000; ++i) {
int intermediateResult = i + 2;
System.out.println(intermediateResult);
}
我也按照这个
答案中的方法,对这两种情况的代码进行了反汇编。我只展示与答案相关的部分。
循环外部情况
Code:
stack=2, locals=3, args_size=1
0: iconst_0
1: istore_2
2: iload_2
3: sipush 1000
6: if_icmpge 26
9: iload_2
10: iconst_2
11: iadd
12: istore_1
13: getstatic
16: iload_1
17: invokevirtual
20: iinc 2, 1
23: goto 2
26: return
LocalVariableTable:
Start Length Slot Name Signature
13 13 1 intermediateResult I
2 24 2 i I
0 27 0 args [Ljava/lang/String;
循环内部情况
Code:
stack=2, locals=3, args_size=1
0: iconst_0
1: istore_1
2: iload_1
3: sipush 1000
6: if_icmpge 26
9: iload_1
10: iconst_2
11: iadd
12: istore_2
13: getstatic
16: iload_2
17: invokevirtual
20: iinc 1, 1
23: goto 2
26: return
LocalVariableTable:
Start Length Slot Name Signature
13 7 2 intermediateResult I
2 24 1 i I
0 27 0 args [Ljava/lang/String;
如果你仔细观察,只有在
LocalVariableTable
中分配给
i
和
intermediateResult
的
Slot
根据它们出现的顺序进行了交换。同样的差异在其他代码行中也有体现。
- 没有执行额外的操作
intermediateResult
在两种情况下仍然是一个本地变量,因此访问时间没有区别。
奖励
编译器进行了大量优化,请看一下这种情况会发生什么。
零工作情况
for(int i=0; i < 1000; i++){
int intermediateResult = i;
System.out.println(intermediateResult);
}
反编译无工作量
for(int i = 0; i < 1000; ++i) {
System.out.println(i);
}