2011-03-02 63 views
5

我有哪裏我聲明瞭一個對象在循環中,如代碼之外的對象的任何性能增益:是否存在被宣告循環

foreach(...) 
{ 
ClassA clA = new ClassA(); 
clA.item1=1; 
clA.item2=2; 
ClassB.Add(clA); 
} 

會有任何性能增益,如果我修改代碼如下:

ClassA clA; 
foreach(...) 
{ 
clA = new ClassA(); 
clA.item1=1; 
clA.item2=2; 
ClassB.Add(clA); 
} 

在此先感謝。

+0

我沒有想到這樣你還是每次創建一個新的ClassA的。你有多少個循環? ClassB.Add是做什麼的? – 2011-03-02 11:13:35

+0

[將在循環內部/外部聲明變量會改變性能嗎?](http://stackoverflow.com/questions/3388536/will-declaring-a-variable-inside-outside-a-loop-change-性能) – 2011-03-02 11:17:14

回答

4

沒有性能增益。它只能幫助變量早於範圍超出範圍。

+1

沒錯。 .NET GC將做一個合適的清理工作。 :) – FarligOpptreden 2011-03-02 11:12:41

+2

如果循環後沒有使用變量,則範圍界定純粹是詞法,即。你可以編寫代碼在更多的地方使用它。但是,對於GC目的而言,它沒有任何區別(至少在沒有附加調試器的Release版本中),只要循環結束,GC就可以回收內存。 – 2011-03-02 11:14:47

+1

我將添加@Farlig所說的內容:MICROSOFT運行時將很容易地看到在循環之後clA不再被使用,並且它也是GC。這不能保證。一個不太智能的JIT無法看到這一點(甚至一個偶然的JIT無法檢查在內部作用域中定義的clA是不是外部複製的,而且可以肯定的是,在下一次GC運行之前不會將其標記出來。我寫了一個很複雜的方式,假設有一個List 在範圍之外,如果你將clA添加到列表中,列表將會保留它,如果你不添加它,列表將不會保留它。愚蠢的JIT無法檢查這個。) – xanatos 2011-03-02 11:17:38

3

編譯器會自動優化代碼以將聲明移到循環之外,所以這樣做沒有任何好處。

例如

while(...){ 
    int i = 5; 
    ... 
} 

將得到優化是編譯器到這

int i; 
while(...){ 
    i = 5; 
    ... 
} 
+3

順便說一句,這兩個並不等價:第一個在每個循環的頂部初始化'i'到5。你對這個聲明是正確的,這只是你的代碼示例是混亂的。第二個會更好,因爲我int; while(...){i = 5; ''。 – paxdiablo 2011-03-02 11:14:28

+0

@pax - Ops!現在修復了我的代碼。謝謝。 – 2011-03-02 13:02:41

1

實際的對象分配情況與clA = new ClassA();所以,除非你可以把它移到圈外的,你不會得到任何性能增益。

1

由於每個人的說,不是真的,但我還是會改變你的代碼:

foreach(...) 
{ 
ClassB.Add(new ClassA() { item1=1, item2=2 }); 
} 
+0

你當然可以做到這一點,但你爲什麼認爲這是可取的? – 2011-03-03 04:40:44

+0

只是因爲它看起來更好......(沒有臨時變量只是爲了分配屬性)。雖然你可能想調整空白,但我懶得在SO中對事物進行美化。 – Massif 2011-03-03 08:55:48

相關問題