简体   繁体   中英

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

Which one is faster in Java and why?

  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 (a > b) ? a : b .

Here is the code for Math.max() in Java:

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. 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.

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! 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.

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. This method has an intrinsic version in pretty much every JRE. See the source code of Hotspot in JDK7, vmSymbols.hpp for a list of such intrinsics.

As far as I can tell, Hotspot will try a number of optimizations when it sees a max or min statement; in particular to optimize eg arraycopy . Amongst others, it will actually optimize Math.max(same, same) away.

In other cases, however, it may not optimize much; (a<=b)?a:b may then actually be faster. 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. 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. 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.

Not the same. When you are writing (a > b) ? a : b (a > b) ? a : b you don't have an extra function call, so it will be faster. It's the equivalent of inlining in C++. But this will not make any difference in real life. Math.max(a,b) is more readable so I would use it.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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