2013-04-25 71 views
3

我在List<string>中有大約100,000個句子。內存中不同物體的大小

我試圖用字,每個這些句子的拆分,並添加到一切List<List<string>>其中每個List包含一個句子,其中包含字的另一List。我這樣做是因爲我必須對每個單詞做不同的工作。記憶中單詞的句子與List<List<string>>只有List<string>的大小差異?

其中之一將被存儲在內存中,最終使我在尋找分裂的記憶影響每個句子VS只是string

+3

爲什麼理論化?爲什麼不嘗試並查看程序的總內存會發生什麼?如果您的總數據集不是真的*很大的可能性,無論它是什麼,它都足夠低而不會成爲問題。如果不是,那麼發現仍然很容易。 – Servy 2013-04-25 19:43:32

+0

http://stackoverflow.com/questions/16214954/how-much-ram-c-sharp-application-can-use – Roar 2013-04-25 19:45:59

+0

雖然你可以試試,但實際上我不確定會發生什麼不同的單詞句子將存儲在實習生池 – 2013-04-25 19:47:31

回答

4

我們將從您的List<string>開始。我將假設64位運行時。 32位運行時的編號稍小。

List本身需要大約32個字節(分配開銷,加上內部變量)加上支持的字符串數組。數組開銷是50字節,並且每個字符串需要8個字節的引用。所以如果你有100,000個句子,你至少需要800,000字節的數組。

這些字符串本身需要類似每個26字節的東西,每個字符加上兩個字節。所以如果你的平均句子是80個字符,你需要每個字符串186個字節。乘以100K字符串,即大約18.5兆字節。總之,您的句子列表大約需要20 MB(整數)。

如果將句子拆分爲單詞,則現在有100,000個List<string>實例。對於List<List<string>>,大約需要5兆字節。如果我們假設每個句子有10個單詞,那麼每個句子的列表將需要支持數組大約80個字節,每個字符串(總共大約260個字節)加上26個字節,再加上字符串數據本身(8個字符或總共160個字節)。因此,每個句子花費你(再次,整數)80 + 260 + 160或500字節。乘以100,000個句子,即50 MB。

所以,非常粗略的數字,將句子拆分爲List<List<string>>將佔用55或60兆字節。

4

所以,第一關我們將在內存比較單一字符串之間的區別或兩個字符串,如果concatted在一起,將導致第一:

string first = "ab"; 

string second = "a"; 
string third = "b"; 

多少內存first使用相比secondthird在一起嗎?那麼他們需要參考的實際字符是相同的,但是every single string object has a small overhead(32位系統上的14個字節,64位系統上的26個字節)。

因此,對於分成List<string>代表較小字符串的每個字符串,都會有一個14 * (wordsPerSentance - 1)字節開銷。

然後,列表本身的開銷。該列表將消耗一個添加到列表中的每個項目的內存(32位系統上的32位,64位系統上的64位等)的一個字加上List<string>本身的開銷(這是32位上的24個字節系統)。

因此,您需要添加(在32位系統上)(24 + (8 * averageWordsPerSentance)) * numberOfSentances字節的內存。

+0

「List」的開銷是分配開銷,加上Count和Capacity的內存以及數組分配開銷(大約50字節:正常的24字節分配開銷加上元數據)。 – 2013-04-25 20:00:16

1

不幸的是,這不是一個非常容易回答的問題 - 它取決於特定的字符串,以及您希望優化的長度。

例如,請查看String.Intern()方法。如果你實習所有的單詞,那麼收集的單詞可能會比句子的集合要少。這取決於內容。但是,實習生還有其他的影響,所以這可能不是最好的主意。同樣,這取決於具體情況 - 請檢查鏈接的文檔頁面的「性能考慮」部分。

我認爲最好的做法是在操作前後使用GC.GetTotalMemory(true)來粗略瞭解實際使用的內存量。

+0

實習會導致相同或更少的記憶,可能少得多,可能只是少一點,但不會更多。但是,這是以CPU週期爲代價的。所以如果你願意花費更多的時間來使用更少的內存,那就值得實習。 – Servy 2013-04-25 20:08:40

+0

那麼,在退化的情況下,每個單詞只出現一次,由於所有額外字符串實例的開銷,空終止符,額外的'列表's和whatnot ,但是,總的來說,它可能會節省空間。但是,即使在收集字符串實例之後,也存在內存不會被回收的問題。 – 2013-04-25 21:04:37