为什么将 python 'shelve' 转换为 'dict' 使用这么多内存?
why does converting a python 'shelve' to 'dict' use so much memory?
我有一个非常大的 python 搁置对象(磁盘上有 6GB)。我希望能够将它移动到另一台机器上,并且由于架子不可移动,所以我想对其进行 cPickle。为此,我首先必须将其转换为字典。
出于某种原因,当我执行 dict(myShelf)
时,ipython 进程会占用高达 32GB 的内存(我所有的机器都有),然后似乎挂起(或者可能只需要很长时间).
谁能解释一下?也许提供一个潜在的解决方法?
编辑:使用 Python 2.7
根据我的经验,我认为酸洗比您目前所做的更耗费内存。但是,创建 dict
会立即将货架中的每个键和值加载到内存中,您不应该假设因为您的货架在磁盘上有 6GB,所以它在内存中只有 6GB。例如:
>>> import sys, pickle
>>> sys.getsizeof(1)
24
>>> len(pickle.dumps(1))
4
>>> len(pickle.dumps(1, -1))
5
所以,一个非常小的整数比 Python int
对象(在我的机器上)大 5-6 倍。
至于解决方法:您可以将多个腌制对象写入一个文件。所以不要将架子转换为 dict
,只需将一长串键和值写入您的文件,然后在另一侧读取同样长的键和值序列以放入您的新架子。这样你一次只需要一个 key/value 对在内存中。像这样:
写入:
with open('myshelf.pkl', 'wb') as outfile:
pickle.dump(len(myShelf), outfile)
for p in myShelf.iteritems():
pickle.dump(p, outfile)
阅读:
with open('myshelf.pkl', 'rb') as infile:
for _ in xrange(pickle.load(infile)):
k, v = pickle.load(infile)
myShelf[k] = v
我认为您实际上不需要存储长度,您可以继续阅读,直到 pickle.load
抛出一个异常,表明它 运行 文件外。
我有一个非常大的 python 搁置对象(磁盘上有 6GB)。我希望能够将它移动到另一台机器上,并且由于架子不可移动,所以我想对其进行 cPickle。为此,我首先必须将其转换为字典。
出于某种原因,当我执行 dict(myShelf)
时,ipython 进程会占用高达 32GB 的内存(我所有的机器都有),然后似乎挂起(或者可能只需要很长时间).
谁能解释一下?也许提供一个潜在的解决方法?
编辑:使用 Python 2.7
根据我的经验,我认为酸洗比您目前所做的更耗费内存。但是,创建 dict
会立即将货架中的每个键和值加载到内存中,您不应该假设因为您的货架在磁盘上有 6GB,所以它在内存中只有 6GB。例如:
>>> import sys, pickle
>>> sys.getsizeof(1)
24
>>> len(pickle.dumps(1))
4
>>> len(pickle.dumps(1, -1))
5
所以,一个非常小的整数比 Python int
对象(在我的机器上)大 5-6 倍。
至于解决方法:您可以将多个腌制对象写入一个文件。所以不要将架子转换为 dict
,只需将一长串键和值写入您的文件,然后在另一侧读取同样长的键和值序列以放入您的新架子。这样你一次只需要一个 key/value 对在内存中。像这样:
写入:
with open('myshelf.pkl', 'wb') as outfile:
pickle.dump(len(myShelf), outfile)
for p in myShelf.iteritems():
pickle.dump(p, outfile)
阅读:
with open('myshelf.pkl', 'rb') as infile:
for _ in xrange(pickle.load(infile)):
k, v = pickle.load(infile)
myShelf[k] = v
我认为您实际上不需要存储长度,您可以继续阅读,直到 pickle.load
抛出一个异常,表明它 运行 文件外。