我知道,像我这样查询defaultdict中不存在的键会向defaultdict添加项。这就是为什么在性能方面比较我的第二个代码片段和第一个代码片段是公平的。在import numpy as num
from collections import defaultdict
topKeys = range(16384)
keys = range(8192)
table = dict((k,defaultdict(int)) for k in topKeys)
dat = num.zeros((16384,8192), dtype="int32")
print "looping begins"
#how much memory should this use? I think it shouldn't use more that a few
#times the memory required to hold (16384*8192) int32's (512 mb), but
#it uses 11 GB!
for k in topKeys:
for j in keys:
dat[k,j] = table[k][j]
print "done"
这是怎么回事?此外,与第一个脚本相比,这个类似的脚本运行时间长达数年之久,而且还使用了荒谬的内存量。在
^{pr2}$
我猜python int可能是64位的int,这可能是其中的一部分,但是这些相对自然和简单的构造真的会产生如此巨大的开销吗?
我想这些脚本表明了它们的存在,所以我的问题是:到底是什么导致第一个脚本的内存使用率高,第二个脚本的运行时间长和内存使用率高,有没有办法避免这些开销?在
编辑:
64位计算机上的Python2.6.4。在
编辑2:我明白为什么,按照第一个近似值,我的表应该占用3GB
16384*8192*(12+12)字节
以及6GB的defaultdict负载因子,强制它保留两倍的空间。
然后,内存分配的低效会消耗掉另一个因素2。在
下面是我剩下的问题:
有没有办法告诉它使用32位int?在
为什么我的第二个代码段与第一个代码段相比要花很长时间才能运行?第一个花了大约一分钟,我在80分钟后杀了第二个。在