【问题标题】:No JIT Optimization无 JIT 优化
【发布时间】:2013-07-20 19:48:33
【问题描述】:

看看this question

代码:

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 正在优化的方法调用中。将语句放入有助于优化过程的方法中吗?

【问题讨论】:

  • 这感觉不是一个很实际的问题。你在做一些无用的事情——JIT 优化对你来说真的很重要吗?真正的位代码?
  • 您正在以纳秒为单位测量时间,因此它足够快。在此处查看修改后的毫秒测试 - ideone.com/Xq0xj1

标签: java jit


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

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

【讨论】:

    【解决方案2】:

    循环本身确实会被 jitted(从第二次和第三次执行的运行时间略短观察到),但是消除整个循环是 - 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
    

    【讨论】:

    • 根据您的结果,看起来即使是原始代码也应该通过堆栈替换进行优化。也许只是需要更长的时间?
    • @MarkoTopolnik 我也尝试了具有更大交互计数的原始代码,我的猜测是它首先需要运行 + jit 整个方法至少一次,然后才能得出结论它是安全的优化它。
    • 我认为在每个方法的基础上实现 JIT 编译器/优化器比尝试在方法内的任意块中这样做更可行。所以这似乎也是一个论点,为什么你应该尝试将功能分解成更小的方法,这些方法被其他方法调用。它允许 JIT 独立优化每一项。
    猜你喜欢
    • 2011-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-06
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 2011-12-26
    相关资源
    最近更新 更多