私は何千ものオブジェクトをシリアル化しようとしていますが、これらのオブジェクトのいくつかはラムダオブジェクトです。
cPickle
はラムダでは機能しないため、dill
を使用してみました。ただし、ピクルスを外す(またはディルを外す(?))と、計算速度が10倍以上低下します。ソースを見ると、dill
は内部でpickle
を使用しているようです。これが、速度低下の原因である可能性があります。
両方のモジュールの長所を組み合わせた別のオプションはありますか?
編集:最も重要な速度低下は、ピクリング解除中です。
私はdill
の作者です。はい、dill
は通常遅いですが、それはより堅牢なシリアル化に対して支払うペナルティです。多くのクラスと関数をシリアル化する場合は、dill.settings
のdill
バリアントの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]: