web-dev-qa-db-ja.com

ディルとcPickleの速度差

私は何千ものオブジェクトをシリアル化しようとしていますが、これらのオブジェクトのいくつかはラムダオブジェクトです。

cPickleはラムダでは機能しないため、dillを使用してみました。ただし、ピクルスを外す(またはディルを外す(?))と、計算速度が10倍以上低下します。ソースを見ると、dillは内部でpickleを使用しているようです。これが、速度低下の原因である可能性があります。

両方のモジュールの長所を組み合わせた別のオプションはありますか?

編集:最も重要な速度低下は、ピクリング解除中です。

12
Tohiko

私はdillの作者です。はい、dillは通常遅いですが、それはより堅牢なシリアル化に対して支払うペナルティです。多くのクラスと関数をシリアル化する場合は、dill.settingsdillバリアントの1つを試してみることをお勧めします。byref=Trueを使用する場合は、dillがピクルスになります。参照によるいくつかのオブジェクト(デフォルトよりも高速です)。他の設定は、選択したオブジェクトの選択可能性と速度のトレードオフになります。

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]: 
28
Mike McKerns