编译成字节码占用过多内存
我需要把一个非常大的字典导入到Python中,但遇到了一些意想不到的内存瓶颈。这个字典的结构是这样的:
d = {(1,2,3):(1,2,3,4), (2,5,6)=(4,2,3,4,5,6), ... }
每个键是一个包含三个元素的元组,而每个值是一个相对较小的元组,大小是任意的(通常不会超过30个元素)。字典之所以大,是因为键的数量非常多。我正在处理的一个小例子大约有247257个键。我通过模拟生成这个字典,所以我可以写出一个文本文件来定义这个字典。对于我刚提到的例子,这个文件大小是94MB。现在我遇到的问题是,第一次导入这个字典时,Python编译成字节码时会消耗大约14GB的内存。因此,当我第一次导入字典时,内存使用量会急剧上升,经过大约10秒钟,一切都加载完成。如果.pyc文件已经生成,导入几乎是瞬间完成的。通过使用pympler,我发现这个字典在内存中只占用大约200MB。那么这是怎么回事呢?我还有其他方法可以将这个字典加载到Python中,或者至少编译成字节码吗?我在C++中生成模拟数据,无法以我需要的格式写文件。有没有其他选择(比如Python库等)?我正在与一些需要这个数据作为字典的软件进行接口,所以请不要在这方面给出其他建议。此外,万一你想知道,我在文本文件中定义字典的方式和上面一样,也可以这样定义:
d = {}
d[1,2,3] = (1,2,3,4)
d[2,5,6] = (4,2,3,4,5,6)
...
这两种方式在编译成字节码时都会导致内存激增。事实上,第二种方式似乎稍微更糟,这让我感到惊讶。一定有什么办法可以减少初始编译所需的内存。看起来应该可以逐个键值对地进行编译。有什么想法吗?
其他信息:使用的是Python 2.6.5
7 个回答
这是一个链接,指向Python的官方文档,具体是关于“shelve”这个模块的介绍。这个模块可以帮助你把Python中的数据存储到文件里,就像把东西放进一个架子上,方便以后取用。你可以通过这个链接了解更多关于如何使用这个模块的信息。
我想问题出在,当你解析文件的时候,会生成一个非常庞大的语法树,每个元素都有一点点开销,这些开销加起来就变得很大了。一旦生成了字节码,语法树就不再需要了,所以就被丢掉了,这样就导致了你有200MB的数据。
你有没有试过把数据存储在一个单独的文件里,使用下面的格式,然后在Python中动态加载它呢?
1,2,3=1,2,3
2,5,6=4,2,3,4,5,6
Python脚本应该看起来像这样:
file = open("filename")
d = {}
for line in file:
key, val = line.split("=")
key = tuple(key.split(","))
d[key] = tuple(val.split(","))
file.close()
我猜你的编译时间突然变长,是因为你在做“导入一个包含超级大字典的模块”。不管你是有一个语句还是有247257个单独的赋值语句,整个模块都会一次性被编译。你可以试试把这些赋值语句分开,然后打开文件,一次读取一行,再执行这一行。这样的话,你就只是在编译一行代码,可能会花一些时间。