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

时间:2017-06-22 10:56:27

标签: python numpy serialization pickle dill

我在Ubuntu 16.04上使用Python 2.7和NumPy 1.11.2,以及最新版本的dill(我只是做了pip install 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)

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

编辑:使用Python3,我获得pickledill

相同的效果

PS:我知道numpy.save,但我在一个框架中工作,我将大量不同的对象存储在一个字典中,并存放在一个文件中。

2 个答案:

答案 0 :(得分:7)

我是def pDistp(x1, y1, x2, y2): return (((y2-y1)**2)+((x2-x1)**2))**.5 def numerator(x0, y0, x1, y1, x2, y2): return abs(((y2-y1)*x0)-((x2-x1)*y0)+(x2*y1)-(y2*x1)) x1,y1 = -1,0 x2,y2 = 1,0 x0,y0 = 0,1 print(numerator(x0, y0, x1, y1, x2, y2) / pDistp(x1, y1, x2, y2)) # => 1.0 作者。 dilldill的扩展名,但它确实为pickle和其他对象添加了一些备用的腌制方法。例如,numpy利用dill方法来挖掘数组。

此外,(我相信)numpy默认使用dill(不是DEFAULT_PROTOCOL),对于python3,对于python2,它默认使用HIGHEST_PROTOCOL

答案 1 :(得分:6)

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

在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)