爲了測試代碼中數據結構的開銷,我編寫了下面的測試程序。它假定你的文本文件是ASCII編碼的N
兆字節,相對較短的行。 (我不得不從450改變N
至150後,我的物理存儲器跑出。)
import sys
MB = 1024 * 1024
line = "the quick brown fox jumps over the lazy dog"
megs = 150
nlines = (megs * MB)/len(line)
d = {}
for i in xrange(nlines):
d[i] = line.split(' ')
dict_size = sys.getsizeof(d)
list_size = sum(sys.getsizeof(a) for a in d.items())
item_size = sum(sum(sys.getsizeof(s) for s in a) for a in d.items())
print " dict:", dict_size/float(MB), "MB"
print "lists:", list_size/float(MB), "MB"
print "items:", item_size/float(MB), "MB"
print "total:", (dict_size + list_size + item_size)/float(MB), "MB"
其結果:
dict: 192.00 MB
lists: 251.16 MB
items: 669.77 MB
total: 1112.9 MB
觀看活動監視器,Python的進程超過2千兆字節的內存使用情況的,所以也有一些記憶不算。 malloc
實施的文物可能是一種可能性。
我在C++實現的相同的程序:
#include <string>
#include <vector>
#include <unordered_map>
int main()
{
int const MB = 1024 * 1024;
std::string const line = "the quick brown fox jumps over the lazy dog";
std::vector<std::string> const split = {
"the", "quick", "brown", "fox", "jumps", "over", "the", "lazy", "dog"
};
int const megs = 150;
int const nlines = (megs * MB)/line.size();
std::unordered_map<int, std::vector<std::string>> d;
for (int i = 0; i < nlines; ++i) {
d[i] = split;
}
}
編譯時clang++ -O3
,這使用了大約1GB的內存。 C++沒有sys.getsizeof()
,所以它需要更多的工作來分解內存使用,而我沒有這樣做。
相當於C++的兩倍內存對於Python來說實際上是一個相當不錯的結果,因此我將刪除關於cPython實現的預編輯註釋。
我認爲你的主要問題是將行存儲爲一個短字符串數組。是否可以將線條作爲整個字符串存儲並根據需要分割它們,但不是一次全部分割?
你的程序的最終目標是什麼?
不幸的是,每行至少有100個單詞到1000個單詞!我怎樣才能使我的代碼複雜化? – Arman
其實,如果我把程序改成'line = 10 *「,快速的棕色狐狸跳過懶狗'',內存的使用量就會下降很多,即使是'items'。這是令人驚訝的 - 我只希望「字典」和「列表」開銷下降。 – japreiss
增加了一個C++比較和新的結論,請參閱編輯。 – japreiss