哪一个是在Java中,为什么快?
-
Math.max(a,b)
-
(a>b)?a:b
(这是在采访中问。)
哪一个是在Java中,为什么快?
Math.max(a,b)
(a>b)?a:b
(这是在采访中问。)
Math.max(a, b)
是静态函数(意味着没有虚拟调用的开销),将可能由JVM内联为相同的指令(a > b) ? a : b
(a > b) ? a : b
。
这里是OpenJDK的代码Math.max()
在Java中:
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
因此,代码可能会是(几乎)完全相同的速度。
(让我们说实话,如果你是担心在如此低的水平提高速度,你可能在你的代码更大的问题。)
性能问题总是要求进行测试,然后才能开始投机:
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 );
}
这将运行在我的机器6秒Math.max()
和3.2秒?:
最新的1.6.1 X64服务器的Sun JVM上。 所以?:
实际上要快。 相反,我们都喜欢把在那些由他们仍然不捕获一切的时候真正成为惊人的JIT们的希望。
编辑:出于好奇,我也试了这个代码在同一台机器上的32位客户端JVM 1.6.1以及与此两个版本在7秒内跑! 因此,这可能不是没有得到内联的方法调用但服务器JIT似乎能为这个特殊的测试情况下,当有涉及到一个方法调用它不能检测做一些额外的优化。
不要依赖于投机 。 相反, 基准您的具体使用情况。
一些容易被忽视许多其他的答案的详细信息:
虽然你可以看到一个Java源Math.max
,这其实并不总是会被使用。 该方法在几乎每一个JRE的内在版本。 看到热点在JDK7,源代码vmSymbols.hpp
这种内在的列表。
据我所知,热点会尝试当它看到了一些优化max
或min
的语句; 特别是,以优化例如arraycopy
。 除其他外,它实际上将优化Math.max(same, same)
的路程。
在其他情况下,但是,它可能没有多大优化; (a<=b)?a:b
然后可以实际上会更快。 我一直在基准位,而事实上我经常发现这是更快。 但情况因人而异,它肯定取决于上下文如果热点能够优化一个更好的或其他。 它还将从热点版本有所不同热点的版本...
如果我问这样的问题在接受采访时,我本来期望应聘者告诉我,两个表达式可能不会产生相同的结果对于所有可能的类型a和b。
原来的问题没有指定的参数的类型。 这很重要,因为最大(和最小)的浮点参数定义的更为复杂。 对于浮点(双或浮动)的方法Math.max很可能是较慢的,但它也可能返回不同的结果,如果其中一个参数是NaN。
不一样。 当你写(a > b) ? a : b
(a > b) ? a : b
你不是有一个额外的函数调用做,所以它会更快。 这是内联C ++中的等价物。 但是,这不会让在现实生活中的任何差异。 Math.max(a,b)
是更可读的,所以我将使用它。