2011-12-15 31 views
18

मैं एक कार्यक्रम को क्रमानुसार और बड़ी वस्तुओं deserialize करने की जरूरत है कि लागू करने कर रहा हूँ, इसलिए मैं pickle, cPickle और marshal मॉड्यूल के साथ कुछ परीक्षण कर रहा था सबसे अच्छा मॉड्यूल का चयन करें। जिस तरह से मुझे कुछ बहुत रोचक मिला:मार्शल cPickle भार तेजी से तेजी से उदासीनता,

मैं dumps और फिर loads (प्रत्येक मॉड्यूल के लिए) का उपयोग कर रहा हूं, डिक्ट्स, टुपल्स, इनट्स, फ्लोट और तारों की सूची पर।

DUMPING a list of length 7340032 
---------------------------------------------------------------------- 
pickle => 14.675 seconds 
length of pickle serialized string: 31457430 

cPickle => 2.619 seconds 
length of cPickle serialized string: 31457457 

marshal => 0.991 seconds 
length of marshal serialized string: 117440540 

LOADING a list of length: 7340032 
---------------------------------------------------------------------- 
pickle => 13.768 seconds 
(same length?) 7340032 == 7340032 

cPickle => 2.038 seconds 
(same length?) 7340032 == 7340032 

marshal => 6.378 seconds 
(same length?) 7340032 == 7340032 

तो, इन परिणामों से हम देख सकते हैं कि marshalबेंचमार्क की हिस्सा डंपिंग में बहुत तेज था:

14.8x

यह मेरा बेंचमार्क के उत्पादन में है pickle से 0 गुना तेज और cPickle से 2.6x गुना तेज। pickle से

2.2x गुना तेजी से है, लेकिन 3.1x बार cPickle की तुलना में धीमी:

लेकिन, मेरा बड़ा आश्चर्य के लिए, marshal दूर लोड हो रहा है भाग में cPickle की तुलना में धीमी द्वारा किया गया।

Ubuntu System Monitor

मैं कारण है कि marshal साथ लोड हो रहा है इतनी धीमी गति से किसी भी तरह की लंबाई के साथ संबंधित है अनुमान लगा रहा हूँ:

और राम के लिए के रूप में, marshal जबकि प्रदर्शन लोड हो रहा है भी बहुत अक्षम था इसकी धारावाहिक स्ट्रिंग (pickle और cPickle से अधिक)।

  • क्यों marshal तेजी से डंप और धीमी गति से लोड हो जाता है?
  • क्यों marshal धारावाहिक स्ट्रिंग इतनी लंबी है?
  • क्यों marshal की लोडिंग रैम में इतनी अक्षम है?
  • क्या marshal के लोडिंग प्रदर्शन को बेहतर बनाने का कोई तरीका है?
  • marshalcPickle तेजी से लोडिंग के साथ तेजी से डंपिंग करने का कोई तरीका है?
+0

डाउनवॉटर, साझा करने की देखभाल? – juliomalegria

+3

आपका प्रश्न एक मृत अंत है। 'मार्शल' मॉड्यूल का उपयोग 'अचार' के विकल्प के रूप में नहीं किया जाना है। मार्शल फ़ाइल प्रारूप के लिए कोई आधिकारिक दस्तावेज नहीं है और यह संस्करण से संस्करण में बदल सकता है, इसलिए भविष्य में आपके बेंचमार्क परिणाम गलत हो सकते हैं। –

+0

गति मतभेदों के बारे में: मुझे संदेह है कि यह फाइल आईओ के बारे में है: मार्शल द्वारा उत्पादित फ़ाइल लगभग चार गुना बड़ी है (112 एमबी बनाम 30 एमबी)। –

उत्तर

18

cPicklemarshal से अधिक स्मार्ट एल्गोरिदम है और बड़ी वस्तुओं द्वारा उपयोग की जाने वाली जगह को कम करने के लिए चाल करने में सक्षम है। इसका मतलब है कि यह डीकोड करने के लिए धीमा हो जाएगा लेकिन परिणामी आउटपुट के रूप में एन्कोड करने के लिए तेज़ है। marshal सरल है और ऑब्जेक्ट को सीधे क्रमबद्ध करता है-बिना किसी और विश्लेषण किए। यह भी जवाब देता है कि marshal लोडिंग इतना अक्षम क्यों है, इसे बस अधिक काम करना है - डिस्क से अधिक डेटा पढ़ने में - cPickle जैसी ही चीज़ करने में सक्षम होने के लिए।

marshal और cPickle अंत में वास्तव में अलग अलग बातें कर रहे हैं, क्या तुम सच में दोनों तेजी से बचत और तेजी से लोड हो रहा है नहीं मिल सकता है के बाद से तेजी से बचत कम जो डिस्क के लिए डेटा का एक बहुत बचत का तात्पर्य डाटा संरचनाओं का विश्लेषण करने का तात्पर्य।

तथ्य यह है कि marshal पायथन के अन्य संस्करणों के लिए असंगत हो सकता है के बारे में, आप आमतौर पर cPickle उपयोग करना चाहिए:

हठ "मॉड्यूल" यह एक सामान्य नहीं है "के माध्यम से वस्तुओं सामान्य दृढ़ता और अजगर के हस्तांतरण के लिए। आरपीसी कॉल, मॉड्यूल अचार और शेल्व देखें। मार्शल मॉड्यूल मुख्य रूप से .pyc फ़ाइलों के पाइथन मॉड्यूल के लिए "छद्म-संकलित" कोड पढ़ने और लिखने का समर्थन करने के लिए मौजूद है। इसलिए, पाइथन रखरखाव पिछड़े में मार्शल प्रारूप को संशोधित करने का अधिकार सुरक्षित रखता है असंगत तरीकों की आवश्यकता उत्पन्न होनी चाहिए। यदि आप पाइथन ऑब्जेक्ट्स को क्रमबद्ध और डी-क्रमबद्ध कर रहे हैं, तो इसके बजाय अचार मॉड्यूल का उपयोग करें - प्रदर्शन सी है omparable, संस्करण आजादी की गारंटी है, और अचार मार्शल की तुलना में वस्तुओं की एक विस्तृत श्रृंखला का समर्थन करता है। " (the python docs about marshal)

3

आप देख सकते हैं, उत्पादन cPickle.dump द्वारा उत्पादित उत्पादन marshal.dump द्वारा उत्पादित की लंबाई के 1/4 के बारे में है। इसका मतलब है कि cPickle को डेटा को डंप करने के लिए एक अधिक जटिल एल्गोरिदम का उपयोग करना चाहिए क्योंकि अनियंत्रित चीजें हटा दी गई हैं। डंपेड सूची लोड करते समय, marshal को अधिक डेटा के माध्यम से काम करना पड़ता है जबकि cPickle इसका डेटा जल्दी से संसाधित कर सकता है क्योंकि विश्लेषण करने के लिए कम डेटा होता है।

तथ्य यह है कि marshal पायथन के अन्य संस्करणों के लिए असंगत हो सकता है के बारे में, आप आमतौर पर cPickle उपयोग करना चाहिए:

हठ "मॉड्यूल" यह एक सामान्य नहीं है "के माध्यम से वस्तुओं सामान्य दृढ़ता और अजगर के हस्तांतरण के लिए। आरपीसी कॉल, मॉड्यूल अचार और शेल्व देखें। मार्शल मॉड्यूल मुख्य रूप से .pyc फ़ाइलों के पाइथन मॉड्यूल के लिए "छद्म-संकलित" कोड पढ़ने और लिखने का समर्थन करने के लिए मौजूद है। इसलिए, पाइथन रखरखाव पिछड़े में मार्शल प्रारूप को संशोधित करने का अधिकार सुरक्षित रखता है असंगत तरीकों की आवश्यकता उत्पन्न होनी चाहिए। यदि आप पाइथन ऑब्जेक्ट्स को क्रमबद्ध और डी-क्रमबद्ध कर रहे हैं, तो इसके बजाय अचार मॉड्यूल का उपयोग करें - प्रदर्शन सी है omparable, संस्करण आजादी की गारंटी है, और अचार मार्शल की तुलना में वस्तुओं की एक विस्तृत श्रृंखला का समर्थन करता है। " (the python docs about marshal)

9

इन मील के पत्थरों के बीच का अंतर cPickle को तेज करने के लिए एक विचार देता है:

Input: ["This is a string of 33 characters" for _ in xrange(1000000)] 
cPickle dumps 0.199 s loads 0.099 s 2002041 bytes 
marshal dumps 0.368 s loads 0.138 s 38000005 bytes 

Input: ["This is a string of 33 "+"characters" for _ in xrange(1000000)] 
cPickle dumps 1.374 s loads 0.550 s 40001244 bytes 
marshal dumps 0.361 s loads 0.141 s 38000005 bytes 

पहले मामले में, सूची में एक ही स्ट्रिंग को दोहराता है। दूसरी सूची बराबर है, लेकिन प्रत्येक स्ट्रिंग एक अलग वस्तु है, क्योंकि यह अभिव्यक्ति का परिणाम है। अब, यदि आप मूल रूप से बाहरी स्रोत से अपना डेटा पढ़ रहे हैं, तो आप किसी प्रकार की स्ट्रिंग deduplication पर विचार कर सकते हैं।

11

कुछ लोग इसे एक हैक के बारे में सोच सकते हैं, लेकिन मुझे gc.disable() और gc.enable() के साथ अचार डंप कॉल को लपेटकर बड़ी सफलता मिली है। उदाहरण के लिए, शब्दकोशों के एक ~ 50MB सूची लेखन नीचे snips के लिए 4.

# not a complete example.... 
gc.disable() 
cPickle.dump(params,fout,cPickle.HIGHEST_PROTOCOL)   
fout.close()    
gc.enable() 
+2

वाह, यह वास्तव में काम करता है ... लेकिन क्या असर पड़ता है? – tdc

+0

यह पूरी तरह से काम करता है! मेरे लिए 20x तक भी कुल समय की आवश्यकता है। हालांकि @ क्रिसिस, क्या आप हमें किसी भी प्रतिक्रिया (यदि कोई हो) की ओर इंगित कर सकते हैं? –

+0

@tdc, तेजस, अब आप अब तक ऑब्जेक्टिक ऑब्जेक्ट को डंप नहीं कर पाएंगे, उदा। 'x'' x = [] में; x.append (x) 'Pickler.fast सक्षम होने पर ValueError का कारण बन जाएगा। – kay

5

78 सेकंड से चला जाता है आप cPickle सीसीए बना सकते हैं। सीपीकल के उदाहरण बनाकर 50x (!) तेज़ी से।पिकलर और फिर 1 करने के लिए गैर-दस्तावेजी विकल्प सेट 'तेज':

outfile = open('outfile.pickle') 
fastPickler = cPickle.Pickler(outfile, cPickle.HIGHEST_PROTOCOL) 
fastPickler.fast = 1 
fastPickler.dump(myHugeObject) 
outfile.close() 

लेकिन अगर आपके myHugeObject चक्रीय संदर्भ होते हैं, डंप विधि अंत कभी नहीं होगा।

+0

जानना उपयोगी है! क्या यह भी 'लोड' तेज बनाता है? – juliomalegria

+0

मुझे ऐसा नहीं लगता है, तेज़ विकल्प डेटा को चुनते समय केवल डुप्लिकेट सब-ऑब्जेक्ट डिटेक्शन को अक्षम करता है। आप पाइथन 3 श्रृंखला प्रलेखन (http://docs.python.org/3/library/pickle.html?highlight=pickle#pickle.Pickler.fast) या निश्चित रूप से कोड –

3

आप धारावाहिक परिणाम को संपीड़ित करके स्टोरेज दक्षता में सुधार कर सकते हैं।

मेरा हल यह है कि डेटा को संपीड़ित करना और इसे बेअसर में खिलाना एचडीडी के माध्यम से डिस्क से कच्चे पढ़ने से तेज़ होगा।

नीचे दिया गया परीक्षण यह साबित करने के लिए किया गया था कि संपीड़न अनियमित प्रक्रिया को तेज करेगा। परिणाम अपेक्षा की अपेक्षा नहीं थी क्योंकि मशीन एसएसडी के साथ सुसज्जित थी। एलएच 4 का उपयोग कर डेटा को संपीड़ित करने वाली एचएचडी लैस मशीन पर 60-70 एमबी/एस के बीच डिस्क औसत से पढ़ने के बाद तेज़ होगा।

एलजेड 4: 18% की गति में कमी, संपीड़न अतिरिक्त भंडारण का 77.6% उपज।

marshal - compression speed time 
Bz2 7.492605924606323 10363490 
Lz4 1.3733329772949219 46018121 
--- 1.126852035522461 205618472 
cPickle - compression speed time 
Bz2 15.488649845123291 10650522 
Lz4 9.192650079727173 55388264 
--- 8.839831113815308 204340701 
+0

में अधिक पा सकते हैं दिलचस्प परिणाम! क्या आप यह कह रहे हैं कि आप किसी भी तरह से डेटा को डीकंप्रेस करने से पहले बेकार कर रहे हैं? यदि हां, तो कैसे? – seaotternerd

संबंधित मुद्दे