如何提高大型Python数据结构的反序列化效率?
我有大约170万个“令牌”对象,还有大约13万个“结构”对象,这些结构对象引用了令牌对象,并把它们分组到一起,形成结构。总的来说,这占用了大约800MB的内存,算是比较正常的情况。
为了减少内存占用,我使用了__slots__
,这样我的__getstate__
方法就返回了一些可以被序列化的值的元组,而__setstate__
则把这些值放回原来的位置。我并没有把所有的实例数据都进行序列化,只序列化了令牌的5个项目和结构的7到9个项目,都是字符串或整数。
当然,我使用的是cPickle,并且使用了HIGHEST_PROTOCOL,这个协议的版本是2(适用于python 2.6)。生成的pickle文件大约是120MB。
在我的开发机器上,解压这个pickle文件大约需要2分钟。我想让这个过程更快一些。除了更快的硬件和我现在已经在做的事情,还有什么方法可以帮助我呢?
1 个回答
10
Pickle并不是存储大量相似数据的最佳方法。对于大数据集来说,它可能会很慢,更重要的是,它非常脆弱:如果你改变了源代码,现有的数据集很容易就会坏掉。(我建议你了解一下Pickle的本质:它其实是一堆字节码表达式。这可能会让你考虑其他的数据存储和提取方式。)
你应该考虑使用PyTables,它使用HDF5(跨平台,功能强大)来存储任意大小的数据。你甚至不需要一次性把所有数据都加载到内存中;你可以分块访问数据。你描述的结构听起来非常适合用“表”对象来表示,这种对象有固定的字段结构(包括固定长度的字符串、整数、小的Numpy数组等),可以非常高效地存储大量数据。对于存储元数据,我建议使用表的._v_attrs
属性。