我有很长一段时间都遇到过同样的问题。所以我测试了一个更简单的代码。
结论:在这种情况下,没有性能差异。
外循环情况
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 #2 // Field java/lang/System.out:Ljava/io/PrintStream;
16: iload_1
17: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
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 #2 // Field java/lang/System.out:Ljava/io/PrintStream;
16: iload_2
17: invokevirtual #3 // Method java/io/PrintStream.println:(I)V
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;
如果您密切关注,只有Slot
分配到i
并intermediateResult
在LocalVariableTable
被换为他们的出场顺序的产物。插槽中的相同差异反映在其他代码行中。
- 没有执行额外的操作
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);
}