如果你看看字节码的两个功能,你会发现他们几乎如出一辙:
$ cat test.java
class test {
public static void forfor() {
int width = 15, height = 15;
for (int y = 0; y < height; y++)
for (int x = 0; x < width; x++) {
// do stuff here
}
}
public static void dofor() {
int width = 15, height = 15, y = 0;
do for (int x = 0; x++ < width;) {
// do stuff here
} while (y++ < height);
}
}
$ javac test.java
$ javap -c test
public static void forfor();
Code:
0: bipush 15
2: istore_0
3: bipush 15
5: istore_1
6: iconst_0
7: istore_2
8: iload_2
9: iload_1
10: if_icmpge 32
13: iconst_0
14: istore_3
15: iload_3
16: iload_0
17: if_icmpge 26
20: iinc 3, 1
23: goto 15
26: iinc 2, 1
29: goto 8
32: return
public static void dofor();
Code:
0: bipush 15
2: istore_0
3: bipush 15
5: istore_1
6: iconst_0
7: istore_2
8: iconst_0
9: istore_3
10: iload_3
11: iinc 3, 1
14: iload_0
15: if_icmpge 21
18: goto 10
21: iload_2
22: iinc 2, 1
25: iload_1
26: if_icmplt 8
29: return
唯一真正的区别是,在forfor
,两个条件都在检查开始循环,而在dofor
中,一个在开始时被检查,一个在结束时被检查。考虑到在最里面的循环体中有完全相同的指令,我无法想象该字节码重新排序的任何性能影响。
尽管如此,我相信forfor
方法是两个更好,因为:
- 其用意是显而易见的
- 它不太容易出错(另见在这个问题上找到了一个注释在
dofor
!)
- 如果
height
为零,dofor
将错误地仍然执行循环的一个通过,而forfor
通过完全跳过外循环做正确的事情。
这两种方式都没有什么区别。这不值得担心。 –
它在性能方面很有效率;但在可读性方面效率不高。 –
请注意,这两个循环不是等价的:在最内层循环中,第二种情况下'x'比第一种情况大1。 –