2014-01-29 70 views
4

鑑於這些代碼示例:通過Java中的局部變量在全局聲明靜態值是否有性能優勢?

樣品1個

public class SomeClass { 
    private static final int onlyUsedByMethodFoo = 1; 
    // many lines of code 
    public static void foo() { 
     final String value = items[onlyUsedByMethodFoo]; 
    } 
} 

樣品2

public class SomeClass { 
    // many lines of code 
    public static void foo() { 
     final int onlyUsedByMethodFoo = 1; 
     final String value = items[onlyUsedByMethodFoo]; 
    } 
} 

我更喜歡第二個代碼示例,因爲該值接近於它被使用的地方。它只能由Foo()使用。即使經常調用Foo(),我也沒有看到將其聲明爲全局值的優勢。我所看到的全局靜態值的唯一優勢可能在於性能,但尚不清楚它會帶來多大的性能優勢。也許Java認識到這一點並優化了字節碼。

關於性能,值得在全球範圍內聲明一個常數值嗎?性能增益是否有理由將一個恆定值遠離程序員使用和讀取的位置?

+0

爲什麼性能增益必須從內存中查找值而不是在字節代碼中的方法體中具有字面權限? – Affe

+0

[此問題](http://stackoverflow.com/q/306862/1679863)可能會對您感興趣。 –

+0

這可能會適合更好的[Stack Exchange Code Review](http://codereview.stackexchange.com/) –

回答

5

Java編譯器用它的值來替代此靜態最終字段的所有出現;局部變量是運行時棧幀的一部分。有關更全面的解釋,請參閱The Java® Virtual Machine Specification

我不認爲你的情況在性能上有任何不同。

+1

哇!圍繞這個問題非常熱情!感謝大家的回覆。這個問題來自於我與同事的一次對話,他/她試圖讓我相信全球靜態變量比本地維護更容易維護,性能更好。在閱讀回覆並執行一些本地測試後,我認爲它更好的恕我直言,以保持一個變量接近它使用的地方。似乎沒有顯着的性能影響,它更容易找到,並且仍然與代碼保持一致。感謝大家。我感謝你的時間。 – TERACytE

0

對於這種情況,性能(對於基本類型至少)不是問題。更重要的是「代碼質量」,即代碼的一致性,可讀性和清潔性。 所以,如果你想有一個特定於上下文的變量,請將其定義在真正屬於的位置,並且不要混淆全局上下文

2

首先,這種微型優化並不是真正的細節應該關心自己。如果有的話,你的代碼中涉及更多的部分會有更豐富的性能。

這種微型優化並沒有給你帶來太多的收益,而且你可能會犧牲可讀性,從而忽略性能提升。

您的代碼沒有哪個地方存在巨大的性能瓶頸,所以如果您進行任何微型優化,我不會期望獲得任何主要性能。

爲了您的主要問題,靜態final變量背後的想法是雙重的:

  • 你避免magic numbers,從而使你的意圖明確。
  • 如果你的價值需要改變,你可以在一個地方改變它,而不是幾個地方。

我會爭辯說,如果其他類沒有使用它,那麼它不需要是public。我仍然建議它是一個類變量,所以它的樣式1的樣式,但聲明private static final int onlyUsedByMethodFoo = 1;

0

這不是一個很好的做法,做早熟優化。專注於設計,一個好的設計很容易擴展和維護。如果你有一個好的設計代碼,識別性能問題(如果有的話)不會很麻煩並且可以處理。再次 - 永遠不要做預先優化。而且,現在,編譯器被調優來生成優化的字節碼。

0

特定Java實現/版本的JIT編譯器可以根據它可以推導出的代碼的各種事情來選擇優化。但是,通常,它可以比final方法變量更容易優化類成員。

事實上,所討論的變量是基元(int)可能會改變事物;如果它是一個參考類型,那麼它會更難以優化。既然它不是對象,那麼你可以用引用相等或類似的東西來做任何竅門;考慮這個例子並將其與你的final int

void foo() { 
final Object o = new SomeObject(); 
} 

我認爲,在這種情況下,final不利於性能在所有,因爲語義的預期是,如果你是比較o個別方法調用之間,它應該是一個不同的對象,即它不會從以前的方法調用==o。但是,如果您將其設爲靜態最終類成員,那麼您確實擁有一個單例對象。

這不是我清楚,如果JIT就一定要優化或不優化final的方法,因爲它可以想見,優化它到只有擁有它被存儲在一個地方,但很顯然,以供參考在內存/ CPU方面,類成員將會(稍微)降低開銷。