2010-06-04 55 views
4

所以說例如我正在經歷一個'如果'塊,在這個塊中,我將一些數字的值與一個常量進行比較。難道是這樣的更昂貴:在Java中,創建對象或獲取對象值會更昂貴嗎?

if(foo.getOb().getVal() == CONST_0) 
{ 
    .... 
} 
.... 
if(foo.getOb().getVal() == _CONST_N) 
{ 
    .... 
} 
else 
    .... 

OR:

int x = foo.getOb().getVal(); 
if(x == CONST_0) 
{ 
    .... 
} 
.... 
if(x == _CONST_N) 
{ 
    .... 
} 
else 
    .... 

我知道,這似乎是一個愚蠢的問題。我認爲第二個實現速度更快/效率更高,但我很好奇爲什麼。我一直在想着最近幾分鐘的原因,因爲我對Java的知識...有點欠缺,所以無法真正提出任何事情。

非常感謝任何答案!

+1

爲您的示例生成字節碼並檢查引擎蓋下發生了什麼 – svlada 2010-06-04 16:36:56

+11

讓您的編譯器執行此優化。如果您花時間擔心這一點,請確保您忽略了更重要的問題。 – 2010-06-04 16:39:44

回答

7

它在我看來應該使用switch語句,在這種情況下,您不必擔心它。

switch (foo.getOb().getVal()) { 
    case CONST_0: 
     .... 
     break; 
    case CONST_N: 
     .... 
     break; 
    default: 
     .... 
     break; 
} 
6

這不是創建對象。您正在創建對該對象的引用。

您節省幾個方法,調用(在Java中,他們是非常有效)

的差異可以忽略不計。編譯器不會不太可能優化這些事情。

+1

他的'val'是'int'。所以'=='是唯一的選擇。 – 2010-06-04 16:38:33

+0

a,是的,正在修復。 – Bozho 2010-06-04 16:39:09

+0

沒有'x''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''不必'垃圾收集它是在堆棧上分配的原始類型。 – Justin 2010-06-04 16:51:19

3

假設getOb()getVal()只是返回引用而不做計算,那麼這兩個代碼片斷在功能上是等效的。這意味着它們之間沒有真正明顯的區別。

之間使用哪種形式的辯論涉及到的風格和偏好,以及先發制人的優化邊界問題(因爲你可能會花很多時間爭論使得這對可衡量的影響的變化你的應用程序的性能)。

2

這實際上取決於如何實現getObj()和getVal()。如果他們是昂貴的操作,那麼是的,你的第二個例子幾乎總是會更快。但是,如果您擔心方法調用的開銷,請不要這樣做。 JIT編譯器通常可以經常內聯方法調用,即使不調用,也沒有多少開銷。熟悉堆的局部變量分配,這些操作非常快,除非通過分析確定了性能「熱點」,否則現在就開始考慮更快執行什麼操作爲時尚早。

有關未成熟優化的更多信息,請參閱此處:When is optimisation premature?

通常,寫你的代碼,這樣它的容易理解正確第一。只有當你確定一個明確的瓶頸時,你才應該開始嘗試優化速度/內存。您將通過首先編寫代碼清晰度來節省自己和試圖維護/調試代碼,時間和沮喪的同事。

2

示例代碼違反了Law of Demeter。 它應該是

if(foo.isConst0()) 
{ 
    .... 
} 

無論如何。另外,premature optimization is the root of all evil

+0

所以,要清楚,你建議他實現foo.isConst0(),foo.isConst1(),foo.isConst2()。 。,foo.isConstN()? 看起來超級醜陋,我敢肯定只有foo.getObjVal(),然後檢查值是在德米特的「法則」的限制內。 – biggusjimmus 2010-06-04 18:02:34

+1

向內部狀態請求對象違反了OO。應該有有意義的名字,例如foo.isInStateBar()等。抽象的例子在這裏沒有多大幫助。更好地看到真正有意義的名字。 foo.isInStateBar()比foo.getObj()。getVal()== 3更好 – mhaller 2010-06-04 18:05:37