2016-06-19 17 views
6

Sto provando a serializzare migliaia di oggetti e alcuni di questi oggetti sono oggetti lambda.dill vs cPickle speed difference

Poiché cPickle non funziona per lambda, ho provato a utilizzare dill. Tuttavia, il calo della velocità di calcolo è più di 10 volte quando si seleziona "Unpickleing" (o "undilling" (?)). Guardando attraverso la fonte, sembra che dill usi pickle internamente quale potrebbe essere la ragione per il calo di velocità.

C'è un'altra opzione per me che combini il meglio di entrambi i moduli?

MODIFICA: il calo di velocità più significativo è durante lo spurgo.

+0

di controllo [questa risposta] (http://stackoverflow.com/a/16626757/5741205) – MaxU

+0

Il problema, come ho affermato nella mia domanda, è che 'dill' è troppo lento rispetto al cPickle. – Tohiko

+0

"Gli oggetti serializzati con _PiCloud possono essere de-serializzati usando il normale pickle/cPickle load e load functions._", quindi ho pensato che potesse aiutarti se il tuo rapporto 'serializzazione/desiralization' è' << 1' – MaxU

risposta

14

Sono l'autore dill. Sì, dill è in genere più lento, ma è la sanzione che si paga per una serializzazione più robusta. Se stai serializzando un sacco di classi e funzioni, allora potresti provare una delle varianti dill in dill.settings Se usi byref=True allora dill deciderà più oggetti per riferimento (che è più veloce di default). Altre impostazioni compensano il raccoglitore per la velocità negli oggetti selezionati.

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]: 
+1

Salve @Mike McKerns, quando ho iniziato a usare 'dill' era per queste classi' Python' personalizzate che ho istanziato e che avevano molti tipi di dati complicati all'interno e funzionava perfettamente (quando 'pickle' no). Da allora uso 'dill', ma mi chiedo che tipi di tipi di dati posso usare' pickle' perché ciò non si interromperà? Questo potrebbe essere fuori dallo scopo di un commento, ma mi sento come se fossi l'esperto da quando hai fatto "aneto" per un motivo. –

+2

Vedere https://github.com/uqfoundation/dill/blob/master/dill/_objects.py. È il mio miglior sforzo per tenere traccia di ciò che può essere messo in salamoia e cosa no (con 'dill' e/o' pickle'). Esiste anche un test associato per questo file. Ora, inserendoli nelle classi ... è un po 'più non testato. –