2013-12-11 48 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

但是一個好的優化器可以想出使用這種簡單情況的條件移動。 –