2013-08-27 14 views
13

Uruchomiłem kod, który tworzy duże obiekty, zawierające wiele zdefiniowanych przez użytkownika klas, które następnie trzeba serializować do późniejszego wykorzystania. Z tego, co wiem, tylko wytrawianie jest wystarczająco uniwersalne, by spełnić moje wymagania. Używam cPickle do ich przechowywania, ale generowane obiekty mają rozmiar około 40G, od kodu działającego w 500 MB pamięci. Szybkość serializacji nie jest problemem, ale rozmiar obiektu jest. Czy są jakieś wskazówki lub alternatywne procesy, których mogę użyć, aby ogórki były mniejsze?Zmniejszanie rozmiaru obiektów cPickle

+0

Jakiego protokołu używasz? – user2357112

+0

Protokół wersji 0. Czy 2 stanowiłoby znaczną różnicę? – ddn

+0

To powinno zrobić jakąś różnicę. Nie jestem jednak pewien, ile. – user2357112

Odpowiedz

26

Jeśli trzeba użyć marynatę i nie ma innej metody serializacji działa dla ciebie, zawsze możesz potoczyć pikle przez bzip2. Jedynym problemem jest to, że bzip2 jest trochę slowish ... gzip powinny być szybsze, ale rozmiar pliku jest prawie 2x większy:

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 

Widzimy więc, że rozmiar pliku bzip2 jest prawie 40x mniejsze, gzip jest 20x mniejszy. Gzip jest dość zbliżony do surowego cPickle, jak widać:

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 
+3

Nie wziąłeś pod uwagę lzmy, co uważam za bardzo dobry algorytm. Kiedy użyłem lzma, aby skompresować listę 200000 liczb losowych, to pokonałem gzip i bzip2 (przynajmniej nie sprawdziłem prędkości) –

+0

@Viktor Czy istnieje szybsza serializacja niż cpickle? (Piszesz "żadna inna metoda nie działa dla ciebie") – DreamFlasher

+0

@DreamFlasher Istnieją inne prostsze moduły serializacji, takie jak msgpack, json ... Ale nie tworzą serializacji złożonych obiektów python, tylko podstawowe typy. –

21

Można łączyć rozmowy cPickle dump z na kartę SD:

import cPickle 
import gzip 

def save_zipped_pickle(obj, filename, protocol=-1): 
    with gzip.open(filename, 'wb') as f: 
     cPickle.dump(obj, f, protocol) 

I ponownie załadować spakowany kiszony obiektu:

def load_zipped_pickle(filename): 
    with gzip.open(filename, 'rb') as f: 
     loaded_object = cPickle.load(f) 
     return loaded_object 
+1

czy możesz dodać loadc(), aby go skompletować? – ealeon

+2

@ealeon dodał jeden, mam nadzieję, że to jest to, czego szukasz. – jozzas

Powiązane problemy