【问题标题】:With java jdk 1.7 64-bit, a for loop using an int is 20+ times faster than a for loop with a long. Why?使用 java jdk 1.7 64 位,使用 int 的 for 循环比使用 long 的 for 循环快 20 倍以上。为什么?
【发布时间】:2012-03-24 05:54:10
【问题描述】:

查看下面的修改

终止检查没有进行强制转换。我认为

int:65 毫秒:

public void testWTF() throws Exception {
    int runs = 10;
    long hs = 0;
    long timeSum = 0;
    for (int run = 0; run < runs; run++) {
        int term = Integer.MAX_VALUE;
        long start = System.currentTimeMillis();
        // ***** loop to be tested ******
        for (int i = 0; i < term; i++) {
            hs++;
        }
        timeSum += (System.currentTimeMillis() - start);
        System.out.println("hs = " + hs);
        hs = 0;

    }
    System.out.println("timeSum = " + timeSum);
    System.out.println("avg time = " + (timeSum / runs) + " for " + runs + " runs");
    System.out.println("hs = " + hs);
}

长:1445 毫秒

public void testWTF() throws Exception {
    int runs = 10;
    long hs = 0;
    long timeSum = 0;
    for (int run = 0; run < runs; run++) {
        long term = Integer.MAX_VALUE;
        long start = System.currentTimeMillis();
        // ***** loop to be tested ******
        for (long i = 0; i < term; i++) {
            hs++;
        }
        timeSum += (System.currentTimeMillis() - start);
        System.out.println("hs = " + hs);
        hs = 0;

    }
    System.out.println("timeSum = " + timeSum);
    System.out.println("avg time = " + (timeSum / runs) + " for " + runs + " runs");
    System.out.println("hs = " + hs);
}

硬件:运行 windows 7 64bit 的 64 位 Xeon。

编辑:我对此进行了更新以进行多次迭代。使用 int 版本运行 100 万次,平均时间为 65 毫秒。对于 100 万次、1000 次甚至 100 次,长版本耗时太长。10 次运行的平均时间为 1447 毫秒。

另外,我在循环外使用 hs,这样循环就不会被忽略。

【问题讨论】:

  • 你运行了多次吗?如果您只运行一次,就可以解释巨大的时差。
  • 我无法确认您的结果。使用 int 版本 i 的平均时间为 1475 毫秒,长版本为 1463 毫秒,运行 10 次。在 JDK 7 更新 13 64 位的 Windows 8 64 位上运行

标签: java 64-bit


【解决方案1】:

这是一种非常糟糕/不可靠/不切实际的基准测试方法,因为 JIT 并没有机会进行太多优化——您只运行一次基准测试,然后测量第一次运行。

基本上,一旦 Java 的 JIT 看到您的代码被广泛使用,它就会显着优化您的代码。在实际程序中,JIT 将优化任何关键循环,因此,如果您想要一个模拟现实世界的基准,您必须说服 JIT 参与其中。

在 Java 中获得准确基准的最简单方法是使用 Caliper 之类的工具,该工具知道如何正确预热 JIT 并获得准确的测量结果,然后查看结果是否更加一致。

【讨论】:

  • 看起来 JIT 足够聪明,可以完全消除 int 的循环,可能只是用赋值 hs = term 替换整个循环。 long 的字节码更复杂,可能表明 JIT 不够聪明,无法在这种情况下执行此操作。无论哪种方式,这都不完全是一个现实的基准。
  • 我对其进行了一些修改,以便 hs 必须在循环外使用。这为 int 提供了大约 65 毫秒。
  • 有时可能需要 10000 运行基准测试才能启动 JIT。将 term 降低到更合理的水平,并尝试与运行这两个基准测试进行大量比较。
猜你喜欢
  • 2019-06-07
  • 1970-01-01
  • 2021-10-01
  • 2017-11-29
  • 2012-04-26
  • 2018-07-25
  • 2021-11-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多