2012-02-27 132 views
1

在下面的例子中,我是否需要擔心性能,並保存昂貴調用的結果,還是編譯器意識到它可以執行一次昂貴的調用?Java編譯器優化

String name; 
if (object.expensiveCall() != null) { 
    name = object.expensiveCall().getName(); 
} 
+1

如果結果從數據庫或數據庫獲取數據,則數據會發生變化。所以邏輯上它不會被保存。 – user717572 2012-02-27 17:45:55

+0

它將簡化可以內聯的簡單案例的代碼,並且JVM(不是javac編譯器)可以檢測到沒有副作用。 – 2012-02-27 18:05:48

回答

2

編譯器不會(通常)只進行一次調用,因爲它可能有副作用,或者結果可能不穩定 - 它不可能知道什麼時候你想讓它忽略第二個調用,並且當它實際上需要它時再次撥打電話。您需要保存結果:

final ExpensiveCallResult nullableResult = object.expensiveCall(); 
String name; 
if (nullableResult != null) { 
    name = nullableResult.getName(); 
} 
0

Java編譯器怎麼知道,expensiveCall沒有副作用?在一般情況下 - 它不能。另外:您可以隨時重新編譯object的類,而無需重新編譯當前的類。如果expensiveCall有副作用現在會發生什麼?沒有辦法自動優化。

順便說一句:JIT編譯器在運行時可能有更多的信息。但昂貴的調用通常不考慮內聯,因此也沒有進一步的優化步驟。

0

不,你將需要重寫它只能撥打電話一次:

String name; 
MyResult result = object.expensiveCall(); 
if (result != null) { 
    name = result.getName(); 
} 

您也可以縮短語法來進行分配,並在同一行檢查:

String name; 
MyResult result; 
if ((result = object.expensiveCall()) != null) { 
    name = result.getName(); 
} 
1

您正在尋找名爲memoization的物品。 This question表明Java本身不能做到這一點。

一般而言,只有在編譯器/ JIT可以證明該函數沒有副作用時纔可以進行記憶。所以我不會指望它。

但是真的很難保存結果嗎?

String name; 
ObjectType temp = object.expensiveCall(); 
if (temp != null) { 
    name = temp.getName(); 
} 
0

在將來你可以編譯和反編譯類回來JAD看看編譯器優化。

在你的情況下,它不會優化任何東西。