给出以下(直接的)代码:
public class pr1 {
public static void f1(){
long sx = 0, s;
s = System.currentTimeMillis();
for(long i = 0; i < Integer.MAX_VALUE; ++i){
sx += i;
}
System.out.println("f1(): " + (System.currentTimeMillis() - s));
}
public static void f2(){
long sx = 0, s, i;
s = System.currentTimeMillis();
i = Integer.MAX_VALUE;
while(i-->0){
sx+=i;
}
sx += Integer.MAX_VALUE;
System.out.println("f2(): " + (System.currentTimeMillis() - s));
}
public static void f3(){
long sx = 0, s, i;
s = System.currentTimeMillis();
i = Integer.MAX_VALUE;
while(--i>0){
sx+=i;
}
sx += Integer.MAX_VALUE;
System.out.println("f3(): " + (System.currentTimeMillis() - s));
}
public static void f4(){
long sx = 0, s, i;
s = System.currentTimeMillis();
i = Integer.MAX_VALUE;
do{
sx+=i;
}while(--i>0);
System.out.println("f4(): " + (System.currentTimeMillis() - s));
}
public static void main(String args[]){
f1();
f2();
f3();
f4();
}
}
运行代码后的实际结果:
f1(): 5828
f2(): 8125
f3(): 3406
f4(): 3781
你能解释一下大时间差吗?理论上循环实现了相同的功能,但实际上每个版本之间存在着显著的时间差。
经过反复执行,结果基本相同。
稍后编辑 作为另一个测试,我已重写了主方法:
public static void main(String args[]){
for(int i = 0; i < 4; ++i){
f1(); f2(); f3(); f4();
}
}
新的结果如下:
f1(): 5906
f2(): 8266
f3(): 3406
f4(): 3844
f1(): 5843
f2(): 8125
f3(): 3438
f4(): 3859
f1(): 5891
f2(): 8156
f3(): 3406
f4(): 3813
f1(): 5859
f2(): 8172
f3(): 3438
f4(): 3828
并且重复10次:
f1(): 5844
f2(): 8156
f3(): 3453
f4(): 3813
f1(): 5844
f2(): 8218
f3(): 3485
f4(): 3937
f1(): 5985
f2(): 8156
f3(): 3422
f4(): 3781
f1(): 5828
f2(): 8234
f3(): 3469
f4(): 3828
f1(): 5844
f2(): 8328
f3(): 3422
f4(): 3859
f1(): 5844
f2(): 8188
f3(): 3406
f4(): 3797
f1(): 5906
f2(): 8219
f3(): 3422
f4(): 3797
f1(): 5843
f2(): 8203
f3(): 3454
f4(): 3906
f1(): 5844
f2(): 8140
f3(): 3469
f4(): 3812
f1(): 5860
f2(): 8109
f3(): 3422
f4(): 3813
在去除循环之间的计算后,结果仍然有些不同:
public class pr2 {
public static void f1(){
long sx = 0, s;
s = System.currentTimeMillis();
for(long i = 0; i < Integer.MAX_VALUE; ++i);
System.out.println("f1(): " + (System.currentTimeMillis() - s));
}
public static void f2(){
long sx = 0, s, i;
s = System.currentTimeMillis();
i = Integer.MAX_VALUE;
while(i-->0);
System.out.println("f2(): " + (System.currentTimeMillis() - s));
}
public static void f3(){
long sx = 0, s, i;
s = System.currentTimeMillis();
i = Integer.MAX_VALUE;
while(--i>0);
System.out.println("f3(): " + (System.currentTimeMillis() - s));
}
public static void f4(){
long sx = 0, s, i;
s = System.currentTimeMillis();
i = Integer.MAX_VALUE;
do{
}while(--i>0);
System.out.println("f4(): " + (System.currentTimeMillis() - s));
}
public static void main(String args[]){
for(int i = 0; i < 2; ++i){
f1(); f2(); f3(); f4();
}
}
}
但是时差仍然存在:
f1(): 3219
f2(): 4859
f3(): 2610
f4(): 3031
f1(): 3219
f2(): 4812
f3(): 2610
f4(): 3062
JVM:
java version "1.6.0_20"
Java(TM) SE Runtime Environment (build 1.6.0_20-b02)
Java HotSpot(TM) Client VM (build 16.3-b01, mixed mode, sharing)
后续编辑: 在第一个版本中,我使用了javac的-O参数。新的结果如下:
f1(): 3219
f2(): 4859
f3(): 2610
f4(): 3031
后续编辑
好的,我在家用一台Linux机器尝试了相同的代码,具体配置如下:
java version "1.6.0_18"
OpenJDK Runtime Environment (IcedTea6 1.8) (6b18-1.8-0ubuntu1)
OpenJDK Server VM (build 14.0-b16, mixed mode)
结果是“正常”的。现在没有问题了:
f1(): 7495
f2(): 7418
f3(): 7457
f4(): 7384
f(3)
运行次数比f(2)
少一次,因为在比较之前减小了该值。 - ponzaof3()
再运行f2()
? - ponzao