2013-12-11 25 views
0

鉴于以下Java代码,JRE优化程序将呼叫Math.max替换为max的呼叫吗?Java会优化max操作吗?

未优化的代码

public static void main(String[] args) { 
    int max = max(3, 5); 
} 

public int max(int x, int y) { 
    if (x < y) { 
    return y; 
    } 
    else { 
    return x; 
    } 
} 

优化代码

public static void main(String[] args) { 
    int max = Math.max(3,5) 
} 
+0

通过调用完全不相关的方法进行优化? –

+0

我想知道它是否足够聪明以理解'max'函数的功能语义是什么。如果是,不应该用Math.max或其他等效代码的调用来代替它吗? – RouteMapper

+0

它可能够聪明,但没有这种智能是免费的(这一切都花费时间)。这种优化是你可以轻松完成的事情,编译器专注于你不能做的事情。有些优化可以通过识别模式来完成,但是识别对特定方法的调用要容易得多......这就是内在函数的含义,请参阅我的答案。 – maaartinus

回答

5

号将如何编译器知道他们是一样的吗?

是什么让你认为Math.max会更快?没有任何理由会比你的功能执行得更快。

编译器可能会内联一个这样的简单函数 - 但这是编译器的问题。

想象一下标准程序中有多少个库。编译器需要花费多少精力去扫描所有这些库以获得相同的代码片段。然后看看识别它们的收益有多小。

现在还考虑多个库的情况,其中都定义了这种方法。编译器需要离开这两个库,否则一个库变得依赖于另一个库,如果将来某个库改变或删除了它的方法定义会发生什么。

这是一个巨大的杂乱的蠕虫罐,最终没有真正的好处。

+0

它可能通过某种象征性的执行知道,不是吗? – RouteMapper

+0

请参阅编辑。是的,理论上可以说,但是这样做并没有真正的好处和很多不利影响。 –

+1

你错了w.r.t. “没有任何理由表现得比你的功能更快。” – maaartinus

3

Math.max有一个非常好的理由比手写方法更快:它在内在方法的list上。由于这是一个非常简单的操作,在给定的CPU上可能没有收益,但使用它可能是一个好主意。

对于更复杂的操作,使用内在函数有很大的速度。例如,Long.numberOfLeadingZeros(long)的Java代码很长,并且需要十几个周期(或者更多的分支错误预测)。由于热点JVM知道这种方法,并且有相应的i86指令,所以您可以在一个周期内获得它(甚至为其他指令留下空间同时执行)。

+0

那么,源的版本是几岁,但这里是Math.max:'公共静态int max(int a,int b){返回(a> = b)? a:b; }'。与OP的方法非常相似。坦率地说,一个体面的JITC应该能够优化到约3条指令。 –

+0

我不知道在这里使用intrinsincs的原因是什么,但优化是非平凡的:当分支概率接近0或1时,应该使用条件分支,否则条件移动更好(可能多更好)。请参阅我的[这个问题](http://stackoverflow.com/questions/19689214/strange-branching-performance)。 – maaartinus

+0

但是一个好的优化器可以想出使用这种简单情况的条件移动。 –