Math.max(a,b)或(a> b)?a:b在Java中更快?

gir*_*iri 24 java core

Java中哪一个更快?为什么?

  1. Math.max(a,b)
  2. (a>b)?a:b

(这是在接受采访时被问到的.)

dsi*_*cha 23

Math.max(a, b)是一个静态函数(意味着没有虚拟调用开销),并且可能由JVM内联到相同的指令(a > b) ? a : b.

  • 编译器没有内联JVM指令,JIT探查器内联机器代码:) (4认同)
  • IIRC,JIT实际上不会执行任何优化,直到有问题的块被执行了很多次(数千次).性能问题(尤其是Java)的唯一安全答案是:"这取决于......" (2认同)

jjn*_*guy 22

是Java中的代码Math.max():

public static int max(int a, int b) {
    return (a >= b) ? a : b;
}
Run Code Online (Sandbox Code Playgroud)

因此,代码可能(几乎)完全相同的速度.

(说实话,如果你担心速度提升到如此低的水平,你的代码可能会遇到更大的问题.)

  • @Sinan:当您查看字节码时,您可以看到条件运算符始终是分支,因此使用`> =`而不是`=`只会使它在值相等时使用其他路由.并且当前的Java VM也可以为低级别操作实现惊人的性能,有时甚至很难被C或ASM击败.如果你知道要避免什么,那么高性能和Java不一定是矛盾的. (4认同)
  • 为什么在 `a == b` 上分支会更糟糕?假设“a”和“b”是真正随机的“int”。那么 `a > b` 的分支频率不会和 `a >= b` 一样频繁吗? (2认同)

x4u*_*x4u 12

在开始推测之前,性能问题总是需要测试:

public static void maxtest()
{
    int res = 0;
    for( int idx = 0; --idx != 0; )
        // res = ( res > idx ) ? res : idx;
        res = Math.max( res, idx );
    System.out.println( "res: " + res );
}
Run Code Online (Sandbox Code Playgroud)

在我的机器上运行6秒,在最新的1.6.1 x64服​​务器Sun JVM上运行Math.max()3.2秒?:.所以?:实际上更快.与我们希望放在JIT中的所有希望相反,当他们仍然没有抓住一切时真正变得惊人.

编辑:出于好奇,我也在同一台机器上使用32位客户端JVM 1.6.1尝试了这个代码,并且这两个版本在7秒内运行!所以它可能不是没有内联的方法调用,但是服务器JIT似乎能够为这个特定的测试用例做一些额外的优化,它在涉及方法调用时无法检测到.


Ano*_*sse 6

不要依赖猜测。相反,对您的特定用例进行基准测试。

许多其他答案中一些容易被忽视的细节:

虽然您可以看到 的 Java 源代码Math.max,但实际上并不总是会使用它。该方法在几乎每个 JRE 中都有一个内在版本。有关此类内在函数的列表,请参阅JDK7 中 Hotspot 的源代码。vmSymbols.hpp

max据我所知,Hotspot 在看到or语句时会尝试一些优化min;特别是优化例如arraycopy。其中,它实际上会优化Math.max(same, same)掉。

然而,在其他情况下,它可能不会优化太多;(a<=b)?a:b那么实际上可能会更快。我已经进行了一些基准测试,实际上我经常发现这更快。但是 YMMV,Hotspot 是否可以更好地优化其中之一,这绝对取决于上下文。它也会因热点版本而异......