2012-07-18 18 views
0

我有一個穩定增長的元素列表,直到我將該列表中的所有數據轉儲到文件中。然後我想再次使用該列表來達到同樣的目的。將它簡單地分配給一個新列表是不好的做法,而不是從列表中刪除所有元素?看起來垃圾收集應該照顧舊列表,這樣我就不必擔心刪除元素。讓C#垃圾收集列表而不是重新使用它是不好的形式嗎?

例如:

var myList = new List<element>(); 
myList.Add(someElement); 
myList.Add(anotherElement); 
// dumps the elements into a file 

myList = new List<element>(); 

編輯:即使有解決這個簡單的方法,我想知道太瞭解它的哲學方面。如果有辦法解決垃圾收集問題,是否不好?允許垃圾收集與刪除元素並重用相同內存有什麼關係?

+0

http://stackoverflow.com/questions/3106537/using-the-clear-method-vs-new-object – 2012-07-18 18:53:12

+1

請參閱我的編輯回答評論您的編輯。 – phoog 2012-07-18 19:23:07

+1

我敢打賭,你測量它時不會看到任何區別。但有一件事:當你創建一個新的'List <>'這將是很長的時間,如果你知道它將會變成多久,這是一個優化使用'新列表(容量)''capacity' '是一個'int'。無論是實例化List <>'還是多次執行(重新分配),這都很有用。 – 2012-07-18 19:28:23

回答

6

這取決於列表中有多少元素。如果支持列表的數組足夠大到可以放在大對象堆中,那麼清理列表並重新使用它可能會更好。這將減少大量內存分配的數量,並有助於減少大型對象堆碎片的問題。 (有關詳細信息,請參閱http://msdn.microsoft.com/en-us/magazine/cc534993.aspxhttp://www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/;見http://blogs.msdn.com/b/dotnet/archive/2011/10/04/large-object-heap-improvements-in-net-4-5.aspx對因與.NET 4.5的改進)

如果列表是小,你可能會更好只是創造一個新的列表,或者你可能會得到更好的性能調用Clear()。如有疑問,請測量性能。

編輯:在回答你在編輯提出的哲學問題,這裏有兩個原因來創建一個新的列表:

  1. 在一般情況下,代碼是更清潔和更容易推理,如果你不重用對象。垃圾回收的成本很低,代碼混淆的代價很高。
  2. 考慮如果轉儲列表內容的代碼位於另一個函數中,會發生什麼情況,因爲它很可能是。一旦將該列表從其本地上下文中刪除,可能會有非本地引用到同一列表。其他代碼可能會修改列表,或者可能假設(不正確)您沒有修改它。
5

myList.Clear()myList = new List<element>();

msdn: List.Clear Method

列表中的每個元素都是不同的對象本身更容易代碼,並且將需要被垃圾收集是否清空列表,或重新創建一個新的列表,或一次刪除一個項目。如果你只是清除列表並重用列表本身,那麼不需要垃圾收集。除非你的清單很大,包含成百上千的項目,否則很難衡量性能差異。幸運的是,垃圾收集器是高度優化的,這是一個罕見的情況,開發人員需要考慮它在做什麼。 (正如其他人已經指出的那樣,涉及到各種因素,例如......你將在新列表中添加多少個元素?與舊列表中的元素數量有多少?......但重點是:當涉及到收集列表的元素列表本身的垃圾收集是不相關的)

1

我不是專家,但:
製作列表期待的是,GC會「照顧」舊的可能是一個不好的的想法,因爲這是一個糟糕的做法&可能效率低下。
儘管這是一個微型優化,但我會說「設置」新值直到達到list.Count,而繼續到list.Add是最好的方法,因爲那樣你就不會清除或分配不必要的新內存(除非它是大列表,你想要清除空間)
無論如何,我會建議使用List.Clear() - 它可以節省您和GC的麻煩。

+0

看起來好像你在說「這是一個壞主意,因爲這是一個壞主意」 – 2012-07-18 18:57:55

0

重要的觀點是乾淨的代碼。 當您創建一個新的列表時,舊的列表將被GC刪除(如果沒有其他參考)。

0

我寧願使用List.Clear()刪除所有元素以供重新使用。容量保持不變,所以不應該有額外的開銷成本,並讓GC處理內存垃圾收集,以便您可以保持乾淨的代碼。

1

聽起來好像你在問兩個不同的問題。一個是將它設置爲新對象還是隻清除它是可以的,我認爲Eric的回答非常好。第二個是你是否應該忽略GC並讓它在沒有試圖「幫助」它的情況下工作 - 爲此,我會絕對肯定地說。讓框架完成框架所做的工作,並保持不變,直到必須完成。

很多程序員都想深入挖掘,大多數時候它會導致更多的問題,而不是幫助。 GC旨在收集這些東西併爲您清理它們。除非您看到一個非常具體的問題,否則您應該編寫可用的代碼並在收集內容時予以忽略(在適當的情況下,using關鍵字除外)。