在Java中,哪一个更快,为什么?
Math.max(a,b)
(a>b)?a:b
(这是一个面试问题。)
在Java中,哪一个更快,为什么?
Math.max(a,b)
(a>b)?a:b
(这是一个面试问题。)
a
和b
相等时分支,这会使情况变得更糟。我知道有人会谈到方法查找,但是,老实说,如果您关心这个问题,请不要使用Java。当有人看到Math.max
时,他们知道你在做什么,这才是最重要的。 - Sinan Ünüra == b
进行分支会更糟糕?假设 a
和 b
是真正随机的整数,那么 a > b
分支的频率不会比 a >= b
少吧? - Thomas Eding>=
而不是=
只会在值相等时走另一条路线。当前的Java虚拟机可以实现惊人的性能,即使在低级操作方面,有时也很难被C或ASM超越。如果您知道要避免什么,高性能和Java不一定再是矛盾的。 - x4uMath.max(a, b)
是一个静态函数(意味着没有虚函数调用开销),并且很可能会被JVM内联到与(a > b) ? a : b
相同的指令中。
(a>b)?a:b
。或者反过来,优化器能够处理Math.max()的最佳方法是将其转换为(a>b)?a:b
,而这种转换需要时间。 - Edward Falk性能问题总是需要在你开始推测之前进行测试:
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 );
}
使用 Math.max()
时,这在我的机器上需要6秒,而使用 ?:
则需要3.2秒,在最新的1.6.1 x64服务器Sun JVM上。因此,?:
实际上更快。尽管我们希望JIT(即时编译器)能够捕获所有东西,但它们仍然不能做到。
编辑:出于好奇,我还尝试在同一台机器上使用32位客户端JVM 1.6.1运行此代码,并且两个版本都需要7秒!所以问题可能不在于方法调用无法内联化,而在于服务器JIT似乎可以针对这个特定的测试用例进行一些额外的优化,而无法检测到是否涉及方法调用。
Math.max
的定义与您的替代方案略有不同,并且您几乎总是遵循相同的路径(当您不这样做时可能会导致罕见的非最优化情况) - Tom Hawtin - tackline>=
和>
,但执行时间仍然保持不变。 - x4u Math.max
的Java源代码,但实际上并非总是如此。这种方法在几乎每个JRE中都有一个固有版本。请参见 JDK7中Hotspot的源代码, vmSymbols.hpp
以获取此类内置信息列表。 max
或 min
语句时,它会尝试多种优化,特别是针对优化例如 arraycopy
。在其他人中,它实际上会将 Math.max(same,same)
优化掉。(a<=b)?a:b
实际上可能会更快。我一直在进行基准测试,确实经常发现这样做更快。但是,结果可能因情况而异,并且如果Hotspot可以更好地优化其中一个,则肯定取决于上下文。这也会因热点版本而异...原始问题没有指定参数的类型。这很重要,因为浮点参数的最大值(和最小值)的定义更加复杂。对于浮点数(double或float),Math.max方法可能会更慢,但如果其中一个参数是NaN,则它也可能返回不同的结果。
(a > b) ? a : b
时,你没有额外的函数调用,所以它会更快。这相当于在 C++ 中进行内联。
但是在现实生活中,这不会有任何区别。Math.max(a,b)
更易读,所以我会使用它。