2013-08-27 51 views
13

我正在運行創建大對象的代碼,其中包含多個用戶定義的類,然後我必須序列化以備將來使用。從我所知道的情況來看,只有酸洗對於我的要求來說足夠多才多藝。我一直在使用cPickle來存儲它們,但它生成的對象大小約爲40G,這些代碼來自運行在500 MB內存中的代碼。序列化的速度不是問題,但對象的大小是。是否有任何提示或替代過程可以用來使醬菜變小?減小cPickle對象的大小

+0

您使用的是什麼pickle協議? – user2357112

+0

協議版本0. 2會產生實質性差異嗎? – ddn

+0

它應該有所作爲。不過,我不確定這是多少。 – user2357112

回答

26

爲你工作,你總是可以通過bzip2管鹹菜。唯一的問題是,bzip2有點slowish ...... gzip應該更快,但文件大小几乎是2倍大:

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 

所以我們看到,bzip2的文件大小几乎是40倍小, gzip比其小20倍。 gzip與原始cPickle的性能非常接近,如您所見:

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

你沒有考慮到lzma,我發現它是一個非常好的算法。當我用lzma壓縮200000個隨機數的醃製列表時,它被毆打gzip和bzip2(至少在sizewise方面,我沒有檢查速度) –

+0

@Viktor有沒有比cpickle更快的序列化? (你寫「沒有其他方法適合你」) – DreamFlasher

+0

@DreamFlasher還有其他更簡單的序列化模塊,比如msgpack,json ...但是它們不會序列化複雜的python對象,只是基本的類型。 –

21

您可以使用zip文件結合您的cPickle dump電話:

import cPickle 
import gzip 

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

,並重新加載一個壓縮的醃製對象:如果必須使用泡菜和系列化的沒有其他方法

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

你可以添加load()函數來完成它嗎? – ealeon

+2

@ealeon增加了一個,希望這是你的追求。 – jozzas