为什么dill比numpy数组的pickle快得多,磁盘效率更高

Ban*_*ach 5 python serialization numpy pickle dill

pip install dill在Ubuntu 16.04上使用的是Python 2.7和NumPy 1.11.2,以及最新版本的dill(我刚刚做过).

当使用pickle存储NumPy数组时,我发现pickle非常慢,并且存储的数组几乎是"必要"大小的三倍.

例如,在以下代码中,pickle大约慢50倍(1s对50s),并创建一个2.2GB而不是800MB的文件.

 import numpy 
 import pickle
 import dill
 B=numpy.random.rand(10000,10000)
 with open('dill','wb') as fp:
    dill.dump(B,fp)
 with open('pickle','wb') as fp:
    pickle.dump(B,fp)
Run Code Online (Sandbox Code Playgroud)

我以为莳萝只是泡菜的包装纸.如果这是真的,有没有办法让我自己提高泡菜的性能?对于NumPy阵列,通常不建议使用pickle吗?

编辑:使用Python3,我得到相同的性能pickledill

PS:我知道numpy.save,但我在一个框架中工作,我将许多不同的对象存储在一个文件中,所有对象都存在于字典中.

Gaë*_*ten 8

这应该是一个评论,但我没有足够的声誉......我的猜测是,这是由于使用的泡菜协议.

在Python 2上,默认协议为0,最高支持协议为2.在Python 3上,默认协议为3,最高支持协议为4(从Python 3.6开始).

每个协议版本都改进了前一个协议版本,但协议0对于较大的对象尤其缓慢.在大多数情况下应该避免这种情况,除非您需要能够使用极其旧版本的Python读取您的泡菜.协议2已经好多了.

现在,我 dill默认使用pickle.HIGHEST_PROTOCOL,如果情况确实如此,那可能是速度差异很大的原因.您可以尝试使用pickle.HIGHEST_PROTOCOL来查看是否使用莳萝和标准泡菜获得类似的性能.

with open('dill', 'wb') as fp:
    dill.dump(B, fp, protocol=pickle.HIGHEST_PROTOCOL)
with open('pickle', 'wb') as fp:
    pickle.dump(B, fp, protocol=pickle.HIGHEST_PROTOCOL)
Run Code Online (Sandbox Code Playgroud)


Mik*_*rns 8

我是dill作者. dill是它的扩展pickle,但它确实为numpy其他对象添加了一些替代的酸洗方法.例如,dill利用numpy用于酸洗数组的方法.

另外,(我相信)dill使用DEFAULT_PROTOCOL默认(不HIGHEST_PROTOCOL),为python3,和python2它使用HIGHEST_PROTOCOL默认.