奇怪的表现行为

时间:2010-05-16 05:29:23

标签: java performance

我对此感到困惑。

在我的机器中

  • 直接计算:375毫秒
  • 方法计算:3594 ms,约TEN乘以SLOWER
  • 如果我在直接计算之前放置方法计算,则两次都是相似的。

你在机器上检查了吗?

class Test {
    static long COUNT = 50000 * 10000;
    private static long BEFORE;

    /*--------METHOD---------*/
    public static final double hypotenuse(double a, double b) {
        return Math.sqrt(a * a + b * b);
    }
    /*--------TIMER---------*/
    public static void getTime(String text) {
        if (BEFORE == 0) {
            BEFORE = System.currentTimeMillis();
            return;
        }
        long now = System.currentTimeMillis();
        long elapsed = (now - BEFORE);
        BEFORE = System.currentTimeMillis();
        if (text.equals("")) {
            return;
        }
        String message = "\r\n" + text + "\r\n" + "Elapsed time: " + elapsed + " ms";
        System.out.println(message);
    }

    public static void main(String[] args) {
        double a = 0.2223221101;
        double b = 122333.167;
        getTime("");
        /*--------DIRECT CALCULATION---------*/
        for (int i = 1; i < COUNT; i++) {
            Math.sqrt(a * a + b * b);
        }
        getTime("Direct: ");
        /*--------METHOD---------*/
        for (int k = 1; k < COUNT; k++) {
            hypotenuse(a, b);
        }
        getTime("Method: ");
    }
}

4 个答案:

答案 0 :(得分:4)

无论如何,对我来说零差异。

如果有什么事情可以证明基准微优化的风险。不要这样做。这完全是浪费时间。

至于为什么你会看到差异:不知道。我在Win7 Ultimate 64上使用JDK 6u17(32位)和健康的内存大小。也许你正在使用不同的版本。也许这是JIT编译的一个问题。

无论原因是什么,担心方法调用和没有方法调用之间的区别是一种无关紧要的分心。

答案 1 :(得分:2)

我得到了与预期相当的数字。

无论如何,这种微基准测试不会发现任何性能问题。你需要使用一个真正的探查器,你需要让HotSpot预热等等。只需计时一个循环,然后另一个循环不能可靠地比较两个结构的性能。

相关问题

相关链接

  • JavaOne 2002 presentation S-1816 How NOT To Write A Microbenchmark
  • Benchmarking the Java HotSpot VM
      

    您对HotSpot或任何虚拟机进行基准测试的建议是什么?

         

    这里最好的答案是使用真正的应用程序进行基准测试,因为它们是唯一能够产生真正差异的东西。如果无法做到这一点,请使用标准SPEC基准测试,然后使用其他备受推崇的行业基准测试。 应避免使用微量标记,或至少谨慎使用。微基准测试由于优化效果而给出误导性答案是很常见的。

答案 2 :(得分:0)

很难确定,但我怀疑JIT编译器可能能够优化“直接”版本,因为它已经发现从未使用过计算结果。它可能能够做到这一点,因为它具有Math.sqrt无副作用的内置知识。相比之下,更难以确定您的hypotenuse方法是无副作用的。

无论如何,正如其他人所说,当人们试图为Java编写微基准时,这种奇怪的结果很常见。

答案 3 :(得分:0)

如果你真的想进行微工作台标记,那么我建议你使用像Japex(https://japex.dev.java.net/)这样的库来帮助你。另请阅读http://www.ibm.com/developerworks/java/library/j-jtp12214/