Java中哪一个更快?为什么?
Math.max(a,b)
(a>b)?a:b
(这是在接受采访时被问到的。)
答案 0 :(得分:23)
Math.max(a, b)
是一个静态函数(意味着没有虚拟调用开销),并且可能会被JVM内联到与(a > b) ? a : b
相同的指令。
答案 1 :(得分:22)
Here是Java中Math.max()
的{{3}}代码:
public static int max(int a, int b) {
return (a >= b) ? a : b;
}
因此,代码可能(几乎)完全相同的速度。
(说实话,如果你担心速度提升到如此低的水平,你的代码可能会遇到更大的问题。)
答案 2 :(得分:11)
性能问题总是需要测试才能开始推测:
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 );
}
在最新的1.6.1 x64服务器Sun JVM上,Math.max()
在我的机器上运行6秒,在?:
运行?:
。所以{{1}}实际上更快。与我们希望放在JIT中的所有希望相反,当他们仍然没有捕捉到所有东西时,它们真的变得令人惊叹。
编辑:出于好奇,我也在同一台机器上使用32位客户端JVM 1.6.1尝试了这个代码,并且这两个版本在7秒内运行!所以它可能不是没有内联的方法调用,但是服务器JIT似乎能够为这个特定的测试用例做一些额外的优化,当涉及到方法调用时它无法检测到。
答案 3 :(得分:3)
如果我在面试中提出这样的问题,我本来希望候选人告诉我这两个表达可能不会给所有可能类型的a和b提供相同的结果。
答案 4 :(得分:3)
不要依赖猜测。相反,基准您的特定用例。
许多其他答案中的一些容易被忽视的细节:
虽然您可以看到Math.max
的Java源代码,但这实际上并不总是将使用的内容。这种方法在几乎所有JRE中都有内在版本。请参阅source code of Hotspot in JDK7, vmSymbols.hpp
以获取此类内在函数的列表。
据我所知,Hotspot在看到max
或min
语句时会尝试一些优化;特别是优化例如arraycopy
。除此之外,它实际上会优化Math.max(same, same)
。
然而,在其他情况下,它可能没有太多优化; (a<=b)?a:b
实际上可能更快。我已经进行了一些基准测试,事实上我经常发现它更快。但YMMV,如果Hotspot可以更好地优化其中一个,它肯定取决于上下文。它也会有所不同,从热点版本到热点版本......
答案 5 :(得分:2)
原始问题未指定参数的类型。这很重要,因为浮点参数的max(和min)定义更复杂。对于浮点(double或float),Math.max方法可能较慢,但如果其中一个参数为NaN,它也可能返回不同的结果。
答案 6 :(得分:-2)
不一样。当您编写(a > b) ? a : b
时,您没有额外的函数调用,因此它会更快。它相当于C ++中的内联。
但这不会对现实生活产生任何影响。 Math.max(a,b)
更具可读性,因此我会使用它。