这是来自[Java性能]的示例:
public static void main(String[] args){
double d;
long start=System.currentTimeMillis();
for (int i=0;i<10;i++){
d=fblImpl1(50);
}
long end=System.currentTimeMillis();
System.out.println("elapsed time :"+(end-start));
}
private static double fblImpl1(int n){
if(n<0) throw new IllegalArgumentException("Must be >0");
if (n==0) return 0d;
if (n==1) return 1d;
double d =fblImpl1(n-2) +fblImpl1(n-1);
if (Double.isInfinite(d)) throw new ArithmeticException("overflow");
return d;
}
作者说现代JIT会这样优化代码:
long start=System.currentTimeMillis();
long end=System.currentTimeMillis();
System.out.println("elapsed time :"+(end-start));
因为程序在下面没有使用变量“d”。但是在我的测试中,oracle hostspot jdk1.7并没有做这个优化,程序需要运行很长时间才能完成。
@Holger,首先感谢您的回复。根据我对你的话的理解,我修改了代码如下:
public static void main(String[] args) {
for (int i = 0; i < 10000; i++) {
doTest();
}
}
private static void doTest() {
double d;
long start = System.currentTimeMillis();
for (int i = 0; i < 10000; i++) {
d = fblImpl1(50);
}
long end = System.currentTimeMillis();
System.out.println("elapsed time :" + (end - start));
}
private static double fblImpl1(int n) {
//if (n < 0) throw new IllegalArgumentException("Must be >0");
if (n == 0) return 0d;
if (n == 1) return 1d;
double d = fblImpl1(n - 2) + fblImpl1(n - 1);
//if (Double.isInfinite(d)) throw new ArithmeticException("overflow");
return d;
}
但似乎 JIT 仍然没有按照我的预期应用任何优化。有什么不对?
您不需要多次执行 main 方法,因为 JIT 可以编译经常执行的循环,因此不需要 'doTest' 方法。看来问题出在递归上。如果将 fblImpl1 替换为 sum 之类的小东西,则很容易获得所需的效果。
public static void main(String[] args) {
double d;
List<Long> list = new ArrayList<>();
for (int i = 0; i < 50000; i++) {
long start = System.nanoTime();
fblImpl1(20000);
long end = System.nanoTime();
list.add(end - start);
}
for(long z : list) {
System.out.println(z);
}
}
public static double fblImpl1(int n) {
int sum = 0;
for(int i = 0; i < n; i++) {
sum += i;
}
return sum;
}
下面的代码产生的结果如下:首先,该代码被真正执行,然后得到零。5812 5811 5812 5812 5812 5812 6088 6089 5812 6089 5812 5812 5811 5812 6089 6088 5812 .... 0 0 0 0 0 0 0 0 0 0 0 0 0 0
我使用以下标志执行了代码:
-XX:+PrintCompilation -XX:-TieredCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining
提示:不要使用 SystemCurrentTimeMillis,因为它的精度很差(尤其是在 Windows 上)
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句