gpt4 book ai didi

Java 循环优化

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:04:32 24 4
gpt4 key购买 nike

给出以下(直接的)代码:

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

虚拟机:

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

最佳答案

您实际上是在对 JVM 进行基准测试,而不是代码。

另见:


更新:好的,这个回答有点草率。使用后缀运算符 (i--) 的循环似乎比使用前缀运算符 (--i) 的循环慢。这可能是真的,因为值在表达式求值期间发生了变化,但编译器需要保留原始值的副本以在表达式中使用。使用前缀运算符避免了保留副本的需要,因为表达式中只会使用更改的值。

另见:

毕竟,这种微优化会在 231 次执行中为您节省一到两秒。你真的也经常执行它吗?我更喜欢可读性而不是过早的优化。

关于Java 循环优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3290233/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com