5

我使用JMH 来指定操作的复杂性。如果您从未与 JMH 合作过,请不要担心。JMH 将estimateOperation多次启动该方法,然后获取平均时间。

问题:[窄]这个程序Math.cbrt(Integer.MAX_VALUE)每次都会计算吗?还是只计算一次然后返回缓存结果?

@GenerateMicroBenchmark
public  void estimateOperation() {
    calculate();
}

public int calculate() {
    return Math.cbrt(Integer.MAX_VALUE);
}

问题:[广泛]: JVM 是否曾经缓存过方法的结果?

4

4 回答 4

9

方法返回值永远不会被缓存。但是,由于某些优化(如常量折叠常量传播死代码消除循环不变提升方法内联等),JIT 编译器可能会在运行时消除不必要的调用。

例如,如果替换Math.cbrtMath.sqrtMath.pow,则在 JIT 编译后根本不会调用该方法,因为该调用将被替换为常量。(优化不适用于cbrt,因为它是一种罕见的方法,它属于 JVM 未内置的本机调用)。

于 2014-06-15T20:48:25.560 回答
2

不。

简而言之,Java 不会缓存方法结果,因为方法每次都可以返回不同的值。

于 2014-06-15T20:18:14.193 回答
2

是的,它会在每次被调用时调用该代码

public int calculate() {
    return Math.cbrt(Integer.MAX_VALUE);
}


public double calculate();
    Code:
       0: ldc2_w        #3                  // double 2.147483647E9d
       3: invokestatic  #5                  // Method java/lang/Math.cbrt:(D)D
       6: dreturn    

要拥有缓存,只需将那个幻数替换为

私有静态最终字段

private static final double NUMBER = Math.cbrt(Integer.MAX_VALUE);
于 2014-06-15T20:23:05.220 回答
2

回答狭窄的问题:这取决于 JVM 实现以及代码的解释方式。

回答广泛的问题:不,因为正如 Anubian 还指出的那样,方法可以在每次调用时返回不同的值。

于 2014-06-15T20:56:26.167 回答