未使用的变量真的会影响 JIT 优化吗?

永儿

这是来自[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] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

jit是否会优化新对象

来自分类Dev

PyPy JIT调用优化

来自分类Dev

没有JIT优化

来自分类Dev

JIT简单优化

来自分类Dev

JIT未优化涉及Integer.MAX_VALUE的循环

来自分类Dev

JIT可以进行此字段访问优化吗?

来自分类Dev

Java JIT编译器优化-在可变变量值缓存方面JIT是否一致?

来自分类Dev

Java JIT编译器优化-在可变变量值缓存方面JIT是否一致?

来自分类Dev

JIT优化和弱引用

来自分类Dev

JIT - 微优化 - if语句消除

来自分类Dev

JIT优化浮动问题

来自分类Dev

JIT优化和弱引用

来自分类Dev

编译器会优化未使用的链接文件吗?

来自分类Dev

JIT是这种行为的原因吗?

来自分类Dev

JIT生成错误的代码吗

来自分类Dev

这种优化会减少内存使用吗?

来自分类Dev

Numba @jit无法优化简单功能

来自分类Dev

C语言会影响gcc中的优化吗?

来自分类Dev

在JIT中使用全局变量会产生垃圾结果

来自分类Dev

JIT取消优化,原因为“约束”。为什么JIT会对方法进行优化?

来自分类Dev

.NET JIT编译器为什么会决定不内联或优化对没有副作用的空静态方法的调用?

来自分类Dev

使用全局变量会影响MATLAB的性能吗?

来自分类Dev

我可以使用LLVM jit生成AVX矢量化代码吗?

来自分类Dev

我现在可以对要通过商店分发的iOS应用程序使用JIT吗?

来自分类Dev

.NET JIT如何优化生成的代码布局?

来自分类Dev

事件调用模式和CLR AMD64 JIT优化

来自分类Dev

Java JIT编译器寄存器优化

来自分类Dev

将对象标记为const会导致更好的优化代码(使用优化编译时)吗?

来自分类Dev

我可以为C#制作自己的JIT \ Interpreter \ Compiler并在Visual Studio中使用它吗?

Related 相关文章

热门标签

归档