在Python中存储大文件的最快方法
我最近在StackOverflow上问了一个问题,关于如何把大的Python对象保存到文件里。之前我遇到过把超大的Python字典转换成字符串,然后用write()
写入文件时出现的问题。现在我在用pickle这个工具。虽然它能用,但生成的文件非常大(超过5GB)。我对处理这么大的文件经验不多。我想知道在把这个pickle文件存储到内存之前,压缩一下它会不会更快,或者说是否可行。
5 个回答
在写入之前,把这个pickle文件压缩得更快,甚至可能是可行的。
当然,这是可能的,但没有必要在写入之前在内存中尝试创建一个明确的压缩副本(因为可能放不下!)。你可以利用内置的标准库功能,让它在写入时自动压缩;)
你可以查看这个链接:http://docs.python.org/library/gzip.html。基本上,你只需要用下面的代码创建一种特殊的流:
gzip.GzipFile("output file name", "wb")
然后就可以像使用普通的file
(用open(...)
创建的文件)一样使用它(或者说用file(...)
创建的文件也一样)。
你可以使用 bzip2 来压缩数据:
from __future__ import with_statement # Only for Python 2.5
import bz2,json,contextlib
hugeData = {'key': {'x': 1, 'y':2}}
with contextlib.closing(bz2.BZ2File('data.json.bz2', 'wb')) as f:
json.dump(hugeData, f)
加载数据的方法如下:
from __future__ import with_statement # Only for Python 2.5
import bz2,json,contextlib
with contextlib.closing(bz2.BZ2File('data.json.bz2', 'rb')) as f:
hugeData = json.load(f)
你也可以用 zlib 或 gzip 来压缩数据,它们的使用方法基本上是一样的。不过,zlib 和 gzip 的压缩效果会比 bzip2(或者 lzma)差一些。
在处理数据序列化时,Python代码会非常慢。如果你尝试用纯Python来实现一个类似于Pickle的功能,你会发现速度超级慢。不过,幸运的是,Python自带的模块在这方面表现得相当不错。
除了cPickle
,还有一个叫marshal
的模块,它的速度快很多。但它需要一个真正的文件句柄(而不是文件样对象)。你可以用import marshal as Pickle
来看看它的区别。我觉得你不太可能做出一个比这个还要快的自定义序列化工具……
这里有一个比较新的Python序列化工具的性能测试。