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


Solution 1:

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.

Solution 2:

Here is the openjdk 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.)

Solution 3:

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.

Solution 4:

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