कुछ संदर्भ सामने हैं कि मैं कहां से आ रहा हूं। कोड स्निपेट अंत में हैं।
जब मैं कर सकता हूं, मैं सुपर उच्च प्रदर्शन समानांतर सीएसवी फ़ाइल रीड्स करने के लिए एच 2 ओ जैसे एक ओपन सोर्स टूल का उपयोग करना पसंद करता हूं, लेकिन यह उपकरण फीचर सेट में सीमित है। मैं अंत में पर्यवेक्षित शिक्षण के लिए H2O क्लस्टर को खिलाने से पहले डेटा साइंस पाइपलाइन बनाने के लिए बहुत सारे कोड लिख रहा हूं।
मैं UCI रेपो से 8GB HIGGS डेटासेट और यहां तक कि डेटा विज्ञान के उद्देश्यों के लिए 40GB CSV फ़ाइलों को मल्टीप्रोसेसिंग लाइब्रेरी के पूल ऑब्जेक्ट और मैप फ़ंक्शन के साथ समानता के बहुत सारे जोड़कर तेजी से पढ़ रहा हूं। उदाहरण के लिए निकटतम पड़ोसी खोजों और डीबीएससीएन और मार्कोव क्लस्टरिंग एल्गोरिदम के साथ क्लस्टरिंग के लिए कुछ समानांतर प्रोग्रामिंग चालाकी की आवश्यकता होती है ताकि कुछ गंभीर रूप से चुनौतीपूर्ण स्मृति और दीवार घड़ी समय की समस्याओं को बायपास किया जा सके।
मैं आमतौर पर पहले ग्नू उपकरण का उपयोग करके भागों में फ़ाइल-वार को तोड़ना पसंद करता हूं और फिर उन सभी को पायथन प्रोग्राम में समानांतर में खोजने और पढ़ने के लिए उन पर ग्लोब-फिल्ममेक करता हूं। मैं आमतौर पर 1000 + आंशिक फ़ाइलों की तरह कुछ का उपयोग करता हूं। इन ट्रिक्स को करने से प्रोसेसिंग स्पीड और मेमोरी लिमिट में काफी मदद मिलती है।
पांडा डेटाफ्रेम .read_csv एकल पिरोया हुआ है ताकि आप समानांतर चालन के लिए नक्शा () चलाकर पांडा को काफी तेज कर सकें। आप यह देखने के लिए htop का उपयोग कर सकते हैं कि सादे पुराने अनुक्रमिक पांडा dataframe.read_csv के साथ, सिर्फ एक कोर पर 100% सीपीयू pd.read_csv में वास्तविक अड़चन है, डिस्क बिल्कुल नहीं।
मुझे जोड़ना चाहिए कि मैं तेज वीडियो कार्ड बस में SSD का उपयोग कर रहा हूं, SATA6 बस में कताई HD नहीं, साथ ही 16 सीपीयू कोर।
इसके अलावा, एक और तकनीक जो मुझे पता चला कि कुछ अनुप्रयोगों में महान काम करता है समानांतर है CSV फ़ाइल एक विशाल फ़ाइल के भीतर सभी को पढ़ती है, प्रत्येक कार्यकर्ता को फ़ाइल में अलग-अलग ऑफसेट करने के बजाय कई बड़ी फ़ाइलों में एक बड़ी फ़ाइल को पूर्व-विभाजित करना शुरू करता है। अजगर की फाइल की तलाश () और प्रत्येक समानांतर कार्यकर्ता में स्ट्रिप्स में बड़ी टेक्स्ट फ़ाइल को पढ़ने के लिए (और) बताएं, अलग-अलग बाइट में स्टार्ट-बाइट और एंड-बाइट के स्थानों पर एक ही समय में सभी समसामयिक ऑफसेट। आप बाइट्स पर एक रेगेक्स फाइंडॉल कर सकते हैं, और लाइनफीड्स की गिनती वापस कर सकते हैं। यह आंशिक राशि है। श्रमिकों के समाप्त होने के बाद जब नक्शा फ़ंक्शन वापस आता है, तो वैश्विक रकम प्राप्त करने के लिए अंत में आंशिक रकम जमा करें।
समानांतर बाइट ऑफसेट चाल का उपयोग करते हुए कुछ उदाहरण बेंचमार्क निम्नलिखित हैं:
मैं 2 फ़ाइलों का उपयोग करता हूं: HIGGS.csv 8 जीबी है। यह UCI मशीन लर्निंग रिपॉजिटरी से है। all_bin .csv 40.4 GB है और मेरे वर्तमान प्रोजेक्ट से है। मैं 2 कार्यक्रमों का उपयोग करता हूं: जीएनयू wc प्रोग्राम जो लिनक्स के साथ आता है, और शुद्ध पायथन फास्ट्रेडरो प्रोग्राम जो मैंने विकसित किया है।
HP-Z820:/mnt/fastssd/fast_file_reader$ ls -l /mnt/fastssd/nzv/HIGGS.csv
-rw-rw-r-- 1 8035497980 Jan 24 16:00 /mnt/fastssd/nzv/HIGGS.csv
HP-Z820:/mnt/fastssd$ ls -l all_bin.csv
-rw-rw-r-- 1 40412077758 Feb 2 09:00 all_bin.csv
ga@ga-HP-Z820:/mnt/fastssd$ time python fastread.py --fileName="all_bin.csv" --numProcesses=32 --balanceFactor=2
2367496
real 0m8.920s
user 1m30.056s
sys 2m38.744s
In [1]: 40412077758. / 8.92
Out[1]: 4530501990.807175
वह कुछ 4.5 जीबी / एस, या 45 जीबी / एस है, फ़ाइल की गति में कमी। यह कोई हार्ड स्पिनिंग नहीं है, मेरे दोस्त। यह वास्तव में एक सैमसंग प्रो 950 एसएसडी है।
नीचे एक ही फ़ाइल के लिए गति बेंचमार्क है जिसे ग्नू wc द्वारा लाइन-काउंट किया गया है, एक शुद्ध सी संकलित कार्यक्रम।
क्या अच्छा है आप देख सकते हैं कि मेरे शुद्ध अजगर कार्यक्रम को अनिवार्य रूप से इस मामले में ग्नू wc संकलित सी कार्यक्रम की गति से मेल खाता है। पायथन की व्याख्या की गई है लेकिन सी संकलित है, इसलिए यह गति का एक बहुत ही दिलचस्प उपलब्धि है, मुझे लगता है कि आप सहमत होंगे। बेशक, डब्ल्यूसी को वास्तव में एक समानांतर कार्यक्रम में बदलने की आवश्यकता है, और फिर यह वास्तव में मेरे अजगर कार्यक्रम से मोजे को हरा देगा। लेकिन जैसा कि यह आज है, ग्नू wc सिर्फ एक अनुक्रमिक कार्यक्रम है। आप वह कर सकते हैं जो आप कर सकते हैं, और अजगर आज समानांतर कर सकते हैं। साइथन संकलन मुझे (कुछ और समय के लिए) मदद कर सकता है। इसके अलावा मेमोरी मैप की गई फ़ाइलों को अभी तक खोजा नहीं गया था।
HP-Z820:/mnt/fastssd$ time wc -l all_bin.csv
2367496 all_bin.csv
real 0m8.807s
user 0m1.168s
sys 0m7.636s
HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=16 --balanceFactor=2
11000000
real 0m2.257s
user 0m12.088s
sys 0m20.512s
HP-Z820:/mnt/fastssd/fast_file_reader$ time wc -l HIGGS.csv
11000000 HIGGS.csv
real 0m1.820s
user 0m0.364s
sys 0m1.456s
निष्कर्ष: C प्रोग्राम की तुलना में शुद्ध पायथन प्रोग्राम के लिए गति अच्छी है। हालांकि, यह सी प्रोग्राम पर शुद्ध पायथन प्रोग्राम का उपयोग करने के लिए पर्याप्त नहीं है, कम से कम linecounting उद्देश्य के लिए। आम तौर पर तकनीक का उपयोग अन्य फ़ाइल प्रसंस्करण के लिए किया जा सकता है, इसलिए यह अजगर कोड अभी भी अच्छा है।
प्रश्न: क्या रेगेक्स को केवल एक बार संकलित करने और इसे सभी श्रमिकों को पास करने से गति में सुधार होगा? उत्तर: रेगेक्स पूर्व-संकलन इस आवेदन में मदद नहीं करता है। मुझे लगता है कि इसका कारण यह है कि सभी श्रमिकों के लिए प्रक्रिया क्रमिकता और सृजन का अधिपत्य हावी हो रहा है।
एक और चीज़। क्या समानांतर CSV फ़ाइल पढ़ने से भी मदद मिलती है? डिस्क अड़चन है, या यह सीपीयू है? स्टैकओवरफ्लो पर कई तथाकथित टॉप रेटेड जवाबों में सामान्य देव ज्ञान होता है जो आपको एक फ़ाइल को पढ़ने के लिए केवल एक थ्रेड की आवश्यकता होती है, सबसे अच्छा आप कर सकते हैं, वे कहते हैं। क्या वे निश्चित हैं, हालांकि?
चलो पता करते हैं:
HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=16 --balanceFactor=2
11000000
real 0m2.256s
user 0m10.696s
sys 0m19.952s
HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=1 --balanceFactor=1
11000000
real 0m17.380s
user 0m11.124s
sys 0m6.272s
अरे हाँ, हाँ यह करता है। समानांतर फाइल रीडिंग काफी अच्छी तरह से काम करती है। अच्छा तो तुम जाओ!
Ps। यदि आप में से कुछ जानना चाहते हैं, तो क्या होगा अगर एक कार्यकर्ता प्रक्रिया का उपयोग करते समय शेष राशि 2 थी? खैर, यह भयानक है:
HP-Z820:/mnt/fastssd/fast_file_reader$ time python fastread.py --fileName="HIGGS.csv" --numProcesses=1 --balanceFactor=2
11000000
real 1m37.077s
user 0m12.432s
sys 1m24.700s
Fastread.py python program के मुख्य भाग:
fileBytes = stat(fileName).st_size # Read quickly from OS how many bytes are in a text file
startByte, endByte = PartitionDataToWorkers(workers=numProcesses, items=fileBytes, balanceFactor=balanceFactor)
p = Pool(numProcesses)
partialSum = p.starmap(ReadFileSegment, zip(startByte, endByte, repeat(fileName))) # startByte is already a list. fileName is made into a same-length list of duplicates values.
globalSum = sum(partialSum)
print(globalSum)
def ReadFileSegment(startByte, endByte, fileName, searchChar='\n'): # counts number of searchChar appearing in the byte range
with open(fileName, 'r') as f:
f.seek(startByte-1) # seek is initially at byte 0 and then moves forward the specified amount, so seek(5) points at the 6th byte.
bytes = f.read(endByte - startByte + 1)
cnt = len(re.findall(searchChar, bytes)) # findall with implicit compiling runs just as fast here as re.compile once + re.finditer many times.
return cnt
PartitionDataToWorkers के लिए हार सिर्फ साधारण अनुक्रमिक कोड है। मैंने इसे छोड़ दिया मामले में किसी और को समानांतर प्रोग्रामिंग की तरह कुछ अभ्यास प्राप्त करना चाहता है। मैंने कठिन भागों को मुफ्त में दे दिया: आपके सीखने के लाभ के लिए परीक्षण किया गया और समानांतर कोड काम कर रहा है।
इसके लिए धन्यवाद: Arno और Cliff और उनके महान सॉफ्टवेयर और निर्देशात्मक वीडियो के लिए H2O परियोजना का ओपन-सोर्स H2O प्रोजेक्ट, जिसने मुझे ऊपर दिखाए गए अनुसार इस शुद्ध अजगर उच्च प्रदर्शन समानांतर बाइट ऑफसेट रीडर के लिए प्रेरणा प्रदान की है। H2O समानांतर फाइल रीडिंग करता है जावा का उपयोग करके, अजगर और आर कार्यक्रमों द्वारा कॉल करने योग्य है, और बड़ी सीएसवी फ़ाइलों को पढ़ने पर ग्रह पर कुछ भी तेजी से तेजी से पागल है।