【问题标题】:Why is Math.max so expensive in Java?为什么 Java 中的 Math.max 如此昂贵?
【发布时间】:2015-07-12 06:37:33
【问题描述】:

我想做以下事情

int sum = x+y;
sum = Math.max(sum,x);

但是那行代码往往比

花费更长的时间
int sum = x+y;
if(x>sum)sum=x;

我希望这不是不恰当的问题,但是有人可以解释为什么会这样吗?

我已经查看了源代码,Java 所做的只是

return (a >= b) ? a : b;

【问题讨论】:

    标签: java math


    【解决方案1】:

    可能是因为 Java 的 Math 类是第一次像任何其他 Singleton 或类似的东西一样被创建,因为在此之前没有人使用它,比如类加载器操作。

    【讨论】:

    • OP:因此,为了在此类性能比较中获得更好的准确性,建议阅读How to write micro benchmarks
    • 哇。为什么这是一个公认的答案?好的,请详细说明:第二次调用Math.max 是否“慢”?
    【解决方案2】:

    方法调用不是免费的(即使忽略 Roey 指出的潜在类负载):它们涉及将参数和返回地址压入堆栈,跳转到代码中的不同位置,将参数从堆栈中弹出,完成工作,将结果压入堆栈,跳回并将结果从堆栈中弹出。

    然而,我怀疑你会发现,如果你在代码中的热点(一个运行了 LOT 的地方)中有一个 Math.max 调用, Oracle 的 JVM 的 JIT 会将其优化为内联操作以加快速度。如果似乎没有任何需要,它不会打扰,更喜欢字节码的编译速度而不是机器码而不是优化;但它是一个两阶段编译器,其中第二阶段开始更积极地优化它在代码中检测到的热点。

    【讨论】:

    • 实际上代码在一个循环中,该循环被执行多次(例如,对于某些输入> 100),它仍然慢得多。但感谢您提出的观点。 +1
    • @KatedralPillon:仅此一项并不能使其成为热点。 JVM 非常聪明地优化何时真正有回报,而不是在没有回报时进行优化。
    【解决方案3】:

    Java 中的微基准测试通常是一项非常艰巨的工作。示例和陈述不能一概而论,并且像往常一样,您的问题的答案是“视情况而定”。 ;)。首先,您在 JDK 实现中看到的 Math.max 的源代码是默认的,在现代硬件上根本不使用。编译器将此调用替换为 CPU 操作。阅读更多here

    这当然不能回答您的问题,为什么您的代码现在“更快”了。可能它根本没有执行,因为死代码消除是一种编译器特性。你能给我们一些周围的代码吗?有关调用频率的详细信息也很有用。有关硬件的详细信息。同样重要的是:如果您进行“测量”,请禁用所有省电功能和所有后台任务。最好是使用类似JMH 干杯本尼

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-05-03
      • 1970-01-01
      • 2019-11-06
      • 1970-01-01
      • 1970-01-01
      • 2011-03-24
      • 2010-12-12
      • 1970-01-01
      相关资源
      最近更新 更多