莳萝vs cPickle速度差异

Toh*_*iko 12 python lambda pickle dill

我试图序列化数千个对象,其中一些对象是lambda对象.

既然cPickle不适用于lambdas,我尝试过使用dill.然而,当解开(或开膛(?))时,计算速度的下降超过10倍.从源头看,似乎内部dill使用pickle可能是速度下降的原因.

对于我来说,还有另一个选项可以结合两个模块的最佳选择吗?

编辑:最显着的速度下降是在unpickleing期间.

Mik*_*rns 30

我是dill作者.是的,dill通常较慢,但这是您为更强大的序列化所付出的代价.如果你要序列化很多类和函数,那么你可能想尝试其中一个dill变体dill.settings 如果你使用byref=True那么dill将通过引用pickle几个对象(这比默认更快).其他设置权衡所选对象的速度可选性.

In [1]: import dill

In [2]: f = lambda x:x

In [3]: %timeit dill.loads(dill.dumps(f))
1000 loops, best of 3: 286 us per loop

In [4]: dill.settings['byref'] = True

In [5]: %timeit dill.loads(dill.dumps(f))
1000 loops, best of 3: 237 us per loop

In [6]: dill.settings
Out[6]: {'byref': True, 'fmode': 0, 'protocol': 2, 'recurse': False}

In [7]: dill.settings['recurse'] = True

In [8]: %timeit dill.loads(dill.dumps(f))
1000 loops, best of 3: 408 us per loop

In [9]: class Foo(object):
   ...:     x = 1
   ...:     def bar(self, y):
   ...:         return y + self.x
   ...:     

In [10]: g = Foo()

In [11]: %timeit dill.loads(dill.dumps(g))
10000 loops, best of 3: 87.6 us per loop

In [12]: dill.settings['recurse'] = False

In [13]: %timeit dill.loads(dill.dumps(g))
10000 loops, best of 3: 87.4 us per loop

In [14]: dill.settings['byref'] = False

In [15]: %timeit dill.loads(dill.dumps(g))
1000 loops, best of 3: 499 us per loop

In [16]: 
Run Code Online (Sandbox Code Playgroud)

  • 请查看https://github.com/uqfoundation/dill/blob/master/dill/_objects.py.我最努力地追踪可以腌制的东西和不能腌制的东西(通过`dill`和/或`pickle`).此文件也有相关的测试.现在,将它们放在类中...这有点未经测试. (4认同)
  • @Mike McKerns,您好,当我开始使用`dill`时,我实例化的是这些自定义的`Python`类,其中包含许多复杂的数据类型,并且可以完美地工作(当`pickle`不起作用时)。从那时起我一直在使用`dill`,但是我想知道可以使用`pickle`的哪些类型的数据类型不会中断?这可能不在评论范围之内,但是我觉得您会成为专家,因为您制作“ dill”是有原因的。 (3认同)