Sto eseguendo il codice che crea oggetti di grandi dimensioni, contenenti più classi definite dall'utente, che devo quindi serializzare per un uso successivo. Da quello che posso dire, solo il decapaggio è abbastanza versatile per le mie esigenze. Ho usato cPickle per memorizzarli, ma gli oggetti che genera sono approssimativamente di 40G, dal codice che viene eseguito in 500 mb di memoria. La velocità di serializzazione non è un problema, ma la dimensione dell'oggetto è. Ci sono suggerimenti o processi alternativi che posso usare per rendere i sottaceti più piccoli?Diminuzione della dimensione degli oggetti cPickle
risposta
Se è necessario utilizzare salamoia e nessun altro metodo di serializzazione funziona per te, puoi sempre convogliare il sottaceto attraverso bzip2
. L'unico problema è che bzip2
è un po 'slowish ... gzip
dovrebbe essere più veloce, ma la dimensione del file è quasi 2x più grande:
In [1]: class Test(object):
def __init__(self):
self.x = 3841984789317471348934788731984731749374
self.y = 'kdjsaflkjda;sjfkdjsf;klsdjakfjdafjdskfl;adsjfl;dasjf;ljfdlf'
l = [Test() for i in range(1000000)]
In [2]: import cPickle as pickle
with open('test.pickle', 'wb') as f:
pickle.dump(l, f)
!ls -lh test.pickle
-rw-r--r-- 1 viktor staff 88M Aug 27 22:45 test.pickle
In [3]: import bz2
import cPickle as pickle
with bz2.BZ2File('test.pbz2', 'w') as f:
pickle.dump(l, f)
!ls -lh test.pbz2
-rw-r--r-- 1 viktor staff 2.3M Aug 27 22:47 test.pbz2
In [4]: import gzip
import cPickle as pickle
with gzip.GzipFile('test.pgz', 'w') as f:
pickle.dump(l, f)
!ls -lh test.pgz
-rw-r--r-- 1 viktor staff 4.8M Aug 27 22:51 test.pgz
Così vediamo che la dimensione del file del bzip2
è quasi 40x più piccola, gzip
è 20 volte più piccolo. E gzip è abbastanza vicino alle prestazioni per il raw cPickle, come puoi vedere:
cPickle : best of 3: 18.9 s per loop
bzip2 : best of 3: 54.6 s per loop
gzip : best of 3: 24.4 s per loop
Non hai preso in considerazione lzma, che trovo sia un ottimo algoritmo. Quando ho usato lzma per comprimere una lista decapata di 200000 numeri casuali, ha battuto gzip e bzip2 (almeno al sice, non ho controllato la velocità) –
@Viktor C'è una serializzazione più veloce di cpickle? (Scrivi "nessun altro metodo funziona per te") – DreamFlasher
@DreamFlasher Esistono altri moduli di serializzazione più semplici come msgpack, json ... Ma non serializzano complessi oggetti python, solo i tipi di base. –
È possibile combinare la chiamata cPickle dump
con un file zip:
import cPickle
import gzip
def save_zipped_pickle(obj, filename, protocol=-1):
with gzip.open(filename, 'wb') as f:
cPickle.dump(obj, f, protocol)
E per ricaricare un oggetto in salamoia con zip:
def load_zipped_pickle(filename):
with gzip.open(filename, 'rb') as f:
loaded_object = cPickle.load(f)
return loaded_object
Quale protocollo di sottaceti stai usando? – user2357112
Protocollo versione 0. 2 farebbe una differenza sostanziale? – ddn
Dovrebbe fare qualche differenza. Non sono sicuro di quanto, però. – user2357112