2012-07-30 63 views
6

我有一個可變的類,裏面有一個私人的List<T>字段。在我的班級的Reset()方法中,我應該使用其Clear()方法清除列表,還是隻將其字段分配給一個新列表?請注意,列表不是公開的,只能由類本身使用。所以分配一個新的列表應該使舊的無法訪問。由於Clear()方法is an O(n) operation,我想知道只是分配一個新列表的缺點是什麼。清除私人收藏或將其設置爲空?

回答

5

我能想到的唯一缺點是如果你需要再次使用列表,你將不得不爲它分配新的空間。

對它進行清零隻會使列表及其內容(假設沒有其他引用)符合GC要求。清除它將刪除項目,但保留分配的內存。

就我個人而言,即使我再次需要它,尺寸也會完全改變。

更新:根據下面的註釋,您聲明這些對象將在一個對象池中進行管理。我會建議創建一個小型分析控制檯應用程序來獲得最終答案。現在討論的內容正在進入你的實現細節和對象池的預期用法,這可以很容易地改變答案。

一般來說,如果你的列表長度沒有太大變化,並且總是需要,我會使用Clear來避免爲列表分配新的內存。如果列表長度容易發生很大變化,或者使用有時很稀疏 - 我會傾向於將它歸零,以便回收內存並通過列表的懶惰實例獲得一些次要好處。

+0

因此,如果我有一個2k字節的字節列表,哪個會更快?我,調用Clear或GC,做重新分配?我問這個是因爲我內部有大約1-2k個帶有這些列表的對象,所以我想確定哪個更好,性能更好。 – 2012-07-30 08:10:13

+0

@ d4wn我個人不會擔心表現,除非你能證明這是一個問題。這取決於你想要對列表做什麼。如果這些項目不再需要,但是您可能需要列表大小或者希望避免爲列表增長重新分配內存,我會「清除」。如果你以後不關心這個列表,或者它可能會縮小很多,我會'list = null; list = new List ()'。在任何一種情況下,GC都會收集許多對象,因此無關緊要。任何潛在的性能差異將是O(n)迭代與列表增長重新分配之間的差異。 – 2012-07-30 08:16:35

+0

所以,還有一個問題:爲什麼我要「避免爲列表增長重新分配內存」?我爲這些對象使用了一個池,只要應用程序正在運行,它們會一遍又一遍地重複使用。每次做重新分配聽起來都很昂貴,但我不太瞭解GC以及這個過程對性能的影響。 – 2012-07-30 08:23:24

0

那麼爲什麼是空的呢?這將這樣的伎倆給你,讓堆上垃圾收集舊列表逗留,而訪問列表中的現有方法可以繼續到一個新的空列表功能:

this.FooList = new List<Foo>(); 
+1

我寫過「爲其字段分配新列表」。我使用「取消」這個詞的原因是因爲它使得字段無法訪問並且允許GC收集它。但是你是對的,我應該編輯這個問題。無論如何,問題是哪個更快,他們對另一個有什麼優勢/劣勢。 – 2012-07-30 08:03:37

+0

將其刪除或重新賦值與GC眼中的相同。如果你將它清空並稍後重新分配,你會得到懶惰實例的溫和益處。 – 2012-07-30 08:06:25

0

Reset呼叫我後會在構造函數被調用後使對象保持與它處於同一狀態。

如果你的構造函數創建了一個新的空List然後這樣做。如果不能使它變成null

+0

這就是我想要決定的。在構造函數中一次性地設置列表,並通過清除它來反覆使用它,或者在需要時懶惰地創建列表,並在Reset中將其設置爲null(或新列表)。 – 2012-07-30 08:12:35

+0

@ d4wn在我看來,我認爲績效不應該推動這個決定。我認爲使它成爲'null'並且延遲加載是最乾淨的,我會這樣做。 – ForkandBeard 2012-07-30 08:21:21

相關問題