简体   繁体   English

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

[英]Is Math.max(a,b) or (a>b)?a:b faster in Java?

Which one is faster in Java and why? Java中哪一个更快?为什么?

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

(This was asked in an interview.) (这是在接受采访时被问到的。)

Math.max(a, b) is a static function (meaning no virtual call overhead) and will likely be inlined by the JVM to the same instructions as (a > b) ? a : b Math.max(a, b)是一个静态函数(意味着没有虚拟调用开销),并且可能会被JVM内联到与(a > b) ? a : b相同的指令(a > b) ? a : b (a > b) ? a : b . (a > b) ? a : b

Here is the code for Math.max() in Java: 是Java中Math.max()代码:

public static int max(int a, int b) {
    return (a >= b) ? a : b;
}

So, the code would probably be (almost) exactly the same speed. 因此,代码可能(几乎)完全相同的速度。

(Lets be honest, if you are worrying about speed improvements at such a low level, you probably have far greater problems in your code.) (说实话,如果你担心速度提升到如此低的水平,你的代码可能会遇到更大的问题。)

Performance questions always call for a test before you can start speculating: 在开始推测之前,性能问题总是需要测试:

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 );
}

This runs on my machine 6 seconds with Math.max() and 3.2 seconds with ?: on the latest 1.6.1 x64 server Sun JVM. 在最新的1.6.1 x64服​​务器Sun JVM上,使用Math.max()运行6秒,使用?:运行3.2秒。 So ?: is actually faster. 那么?:实际上更快。 Contrary to all the hopes we like to put in the JITs that have really become amazing by the time they still don't catch everything. 与我们希望放在JIT中的所有希望相反,当他们仍然没有抓住一切时真正变得惊人。

EDIT: Out of curiosity I also tried this code with the 32 bit client JVM 1.6.1 on the same machine and with this both versions run in 7 seconds! 编辑:出于好奇,我也在同一台机器上使用32位客户端JVM 1.6.1尝试了这个代码,并且这两个版本在7秒内运行! So it's probably not the method invocation that doesn't get inlined but the server JIT seems to be able to do some additional optimizations for this particular test case that it can't detect when there is a method call involved. 所以它可能不是没有内联的方法调用,但是服务器JIT似乎能够为这个特定的测试用例做一些额外的优化,它在涉及方法调用时无法检测到。

Do not rely on speculation . 不要依赖猜测 Instead, benchmark your particular use case. 相反, 基准您的特定用例。

Some easily overlooked details in many of the other answers: 许多其他答案中的一些容易被忽视的细节:

While you can see a Java source of Math.max , this is actually not always what will be used. 虽然您可以看到Math.max的Java源代码,但实际上并不总是使用它。 This method has an intrinsic version in pretty much every JRE. 几乎每个JRE都有​​这种方法的内在版本。 See the source code of Hotspot in JDK7, vmSymbols.hpp for a list of such intrinsics. 有关此类内在函数的列表,请参阅JDK7中的Hotspot源代码, vmSymbols.hpp

As far as I can tell, Hotspot will try a number of optimizations when it sees a max or min statement; 据我所知,Hotspot会在看到maxmin语句时尝试一些优化; in particular to optimize eg arraycopy . 特别是优化例如arraycopy Amongst others, it will actually optimize Math.max(same, same) away. 除此之外,它实际上将优化Math.max(same, same)

In other cases, however, it may not optimize much; 然而,在其他情况下,它可能没有太多优化; (a<=b)?a:b may then actually be faster. (a<=b)?a:b实际上可能更快。 I've been benchmarking a bit, and indeed I often found this to be faster. 我已经进行了一些基准测试,事实上我经常发现它更快。 But YMMV, and it definitely depends on the context if Hotspot can optimize one better or the other. 但YMMV,如果Hotspot可以更好地优化其中一个,它肯定取决于上下文。 It will also vary from hotspot version to hotspot version... 它也会有所不同,从热点版本到热点版本......

如果我在面试中提出这样的问题,我本来希望候选人告诉我这两个表达可能不会对所有可能类型的a和b给出相同的结果。

The original question doesn't specify the type of the arguments. 原始问题没有指定参数的类型。 This matters because the definition of max (and min) for floating point arguments is more complex. 这很重要,因为浮点参数的max(和min)定义更复杂。 For floating point (double or float) the Math.max method is likely to be slower, but it also may return a different result if one of the arguments is NaN. 对于浮点(double或float),Math.max方法可能较慢,但如果其中一个参数为NaN,它也可能返回不同的结果。

Not the same. 不一样。 When you are writing (a > b) ? a : b 在你写作时(a > b) ? a : b (a > b) ? a : b you don't have an extra function call, so it will be faster. (a > b) ? a : b你没有额外的函数调用,所以它会更快。 It's the equivalent of inlining in C++. 它相当于C ++中的内联。 But this will not make any difference in real life. 但这不会对现实生活产生任何影响。 Math.max(a,b) is more readable so I would use it. Math.max(a,b)更具可读性,所以我会用它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM