2010-08-16 74 views
2

任何人都可以告訴我,如果其中的任何一個在Java 1.6下編譯的性能都會比其他編譯器更好?假設爲MyObject是一個領域的一類叫做listField具有getter和setterJava性能:獲取和設置列表

樣品#1:

MyObject obj = new MyObject(); 
List<String> lst = new ArrayList<String>(1); 
lst.add("Foo"); 
obj.setListField(lst); 

樣品#2:

MyObject obj = new MyObject(); 
obj.setListField(new ArrayList<String> (1)); 
obj.getListField().add("Foo"); 

我的想法是創建一個ArrayList的本地實例將創建內存開銷,但是隻要您想添加到列表中,就調用getListField()並不像訪問列表的本地版本那麼快。也許如果有幾個項目要添加到列表中,樣品#1更快,但只有少數項目樣品#2更快?或者編譯器是否會優化它,以便調用getListField()等同於訪問列表的本地版本?

+3

明確地提前優化。 – Tom 2010-08-16 19:02:25

+2

去任何更可讀。 – 2010-08-16 21:23:29

+0

局部變量不需要花費任何東西。一旦將代碼編譯爲本地機器語言,它們通常不會消耗任何內存。(只要代碼仍然被解釋,顯然不足以以任何方式進行優化。) – 2010-08-21 05:15:09

回答

9

有沒有這樣的事情作爲「本地實例」。假設setListField()getListField()是微不足道的方法,應該幾乎沒有性能差異 - 如果這些樣本之間有任何。假設你正在使用HotSpot並且沒有加載覆蓋setListField或getListField的子類,我希望這些方法是內聯的。

你需要明白,當你打電話給setListField()(再次,假設它是一個微不足道的實現),你不是創建列表的副本,或類似的東西。您只是將參考傳遞給列表對象。該參考將被複制到該字段中。非常便宜。同樣,我希望getListField()只是將字段的值 - 參考返回到列表。唯一被複制的是一個引用 - 可能是4或8個字節,具體取決於您的JVM。

個人而言,第一個示例對我來說看起來更簡潔的代碼,但您應該專注於理解這裏發生的事情,而不是比性能更重要的事情。

+0

Jon,顯式ArrayList大小設置爲1的情況如何?當然,這會導致問題。順便說一句,你是我的英雄。 – 2010-08-16 19:08:40

+0

@阿米爾:這只是初始能力。爲什麼會導致任何問題?事實上,無論如何,列表中只有一個項目。是的,將第二項添加到列表中會導致它調整大小(如果列表構造函數不強制執行最小值;我沒有檢查),但我認爲這超出了這個問題的範圍。 – 2010-08-16 19:15:41

+0

你是對的,ArrayList將被分配,而不管它是否立即在MyObject對象上設置。傻我。 關於getListField()只是返回一個內存引用,讓我們假設我需要將一個名爲myArray的字符串數組複製到MyObject對象的listField字段中,而不是1個項目,該數組可以包含數百個項目。調用obj.getListField()。add(myArray [i])數百次比調用lst.add(myArray [i])慢一些,然後在myObject上設置lst?看起來方法調用的開銷至少會產生一些影響。 – Cameron 2010-08-16 19:30:40

0

IMO的編譯器會足夠聰明,以優化這兩個,並沒有任何區別。

0

卡梅倫,

你爲什麼要創建一個ArrayList和它明確大小爲1元?如果它永遠不會超過1個元素,請不要使用列表 - 如果它將會,列表調整大小會損壞您的表現。你提出的問題,恕我直言,是不成問題的。

+0

我正在初始化列表,以便沒有人會指出我應該初始化列表大小。在我的現實世界中,列表大於1,我將它初始化爲這樣。 – Cameron 2010-08-16 19:13:36

0

我認爲要考慮的是爲什麼你只用一個元素創建一個數組列表。這樣,當你添加新的元素到列表中時,內部數組將不得不被擴展,我認爲這會更糟糕。

默認情況下,ArrayList s被設置爲10個元素。

0

相同數量的新的=>相同的表現。

除非性能分析顯示這是瓶頸,否則不應該擔心這個問題