3

看看这个问题

编码:

class test
{
    public static void main(String abc[])
    {
        for( int k=1; k<=3; k++)
        {
            for( int N=1; N<=1_000_000_000; N=N*10)
            {
                long t1 = System.nanoTime();

                int j=1;
                for(int i=0; i<=N; i++)
                    j=j*i;

                long t2 = System.nanoTime() - t1;
                System.out.println("Time taken for "+ N + " : "+ t2);
            }
        }
    }
}

上述代码的输出:

Time taken for 1 : 2160
Time taken for 10 : 1142
Time taken for 100 : 2651
Time taken for 1000 : 19453
Time taken for 10000 : 407754
Time taken for 100000 : 4648124
Time taken for 1000000 : 12859417
Time taken for 10000000 : 13706643
Time taken for 100000000 : 136928177
Time taken for 1000000000 : 1368847843
Time taken for 1 : 264
Time taken for 10 : 233
Time taken for 100 : 332
Time taken for 1000 : 1562
Time taken for 10000 : 17341
Time taken for 100000 : 136869
Time taken for 1000000 : 1366934
Time taken for 10000000 : 13689017
Time taken for 100000000 : 136887869
Time taken for 1000000000 : 1368178175
Time taken for 1 : 231
Time taken for 10 : 242
Time taken for 100 : 328
Time taken for 1000 : 1551
Time taken for 10000 : 13854
Time taken for 100000 : 136850
Time taken for 1000000 : 1366919
Time taken for 10000000 : 13692465
Time taken for 100000000 : 136833634
Time taken for 1000000000 : 1368862705

在循环中,即使 i 的值从 0 开始,表示乘积为零,也没有 JIT 优化。为什么不 ?在上面提供的链接中,我之前将 for 循环放在了 JIT 正在优化的方法调用中。是否将语句放入有助于优化过程的方法中?

4

2 回答 2

5
  1. 在您之前的问题中,JIT 优化了方法的完整代码,start而没有分析方法返回时变量中碰巧出现的数字。这是因为您选择了创建方法void,从而为 JIT 提供了一个非常简单的线索,即任何计算的值都将被丢弃。

  2. 将您当前的示例与上一个问题中的示例进行对比,没有void调用任何方法,因此自然不会发生优化。为什么没有其他优化可以帮助这种完全不同的情况是一个无法回答的问题。在您测试代码的特定 JVM 实现和特定 JVM 调用中没有这样的优化。

于 2013-07-20T11:46:33.253 回答
2

循环本身确实会被抖动(正如第二次和第三次执行的运行时间略低所观察到的那样),但是消除整个循环是-afaik-仅在方法本身执行多次时才完成,因为只有这样 JIT 才有足够的运行时间信息以确保它实际上可以消除它而不会产生任何后果。

如果我更改您的代码,则在第三次调用时会消除循环:

public class LoopJit2 {

    public static void main(String abc[]) {
        for (int x = 0; x < 3; x++) {
            loopMethod();
        }
    }

    private static void loopMethod() {
        for (int N = 1; N <= 1_000_000_000; N = N * 10) {
            long t1 = System.nanoTime();

            int j = 1;
            for (int i = 0; i <= N; i++)
                j = j * i;

            long t2 = System.nanoTime() - t1;
            System.out.println("Time taken for " + N + " : " + t2);
        }
    }
}

时间序列:

Time taken for 1 : 1466
Time taken for 10 : 1467
Time taken for 100 : 2934
Time taken for 1000 : 20044
Time taken for 10000 : 201422
Time taken for 100000 : 1993200
Time taken for 1000000 : 4038223
Time taken for 10000000 : 11182357
Time taken for 100000000 : 111290192
Time taken for 1000000000 : 1038002176
Time taken for 1 : 1466
Time taken for 10 : 1467
Time taken for 100 : 2934
Time taken for 1000 : 20044
Time taken for 10000 : 10755
Time taken for 100000 : 124667
Time taken for 1000000 : 1010045
Time taken for 10000000 : 10201156
Time taken for 100000000 : 103184413
Time taken for 1000000000 : 1019723107
Time taken for 1 : 978
Time taken for 10 : 1467
Time taken for 100 : 1467
Time taken for 1000 : 1955
Time taken for 10000 : 978
Time taken for 100000 : 489
Time taken for 1000000 : 977
Time taken for 10000000 : 977
Time taken for 100000000 : 978
Time taken for 1000000000 : 978
于 2013-07-20T11:48:33.463 回答