2014-10-23 7 views
93

मैं सीखने की कोशिश कर रहा हूं कि पाइथन के multiprocessing पैकेज का उपयोग कैसे करें, लेकिन मुझे map_async और imap के बीच का अंतर समझ में नहीं आता है। मैंने देखा कि map_async और imap दोनों को अतुल्यकालिक रूप से निष्पादित किया गया है। तो मुझे दूसरे पर एक का उपयोग कब करना चाहिए? और मुझे map_async द्वारा लौटाए गए परिणाम को कैसे पुनर्प्राप्त करना चाहिए?multiprocessing.Pool: map_async और imap के बीच क्या अंतर है?

क्या मुझे ऐसा कुछ उपयोग करना चाहिए?

def test(): 
    result = pool.map_async() 
    pool.close() 
    pool.join() 
    return result.get() 

result=test() 
for i in result: 
    print i 

उत्तर

264

वहाँ imap/imap_unordered और map/map_async के बीच दो प्रमुख अंतर हैं:

  1. तरह वे iterable आप उन्हें पारित खपत करते हैं।
  2. जिस तरह से वे परिणाम आपको वापस लौटते हैं।

map एक सूची iterable परिवर्तित (यह मानते हुए कि यह एक सूची पहले से ही नहीं है), टुकड़ों में यह तोड़ने, और Pool में कार्यकर्ता प्रक्रियाओं के लिए उन हिस्सा भेजकर अपने iterable खपत करता है। टुकड़ों में पुनरावर्तनीय तोड़ने से प्रत्येक आइटम को एक समय में एक आइटम प्रक्रियाओं के बीच पुनरावर्तित करने से बेहतर प्रदर्शन होता है - विशेष रूप से यदि पुनरावर्तनीय बड़ा होता है। हालांकि, इसे बदलने के क्रम में पुनरावर्तनीय को एक सूची में बदलना बहुत मेमोरी लागत हो सकता है, क्योंकि पूरी सूची को स्मृति में रखा जाना चाहिए।

imap पुनरावृत्ति को चालू नहीं करता है, आप इसे एक सूची में देते हैं, न ही इसे टुकड़ों में विभाजित करते हैं (डिफ़ॉल्ट रूप से)। यह एक समय में पुनरावर्तनीय एक तत्व पर फिर से शुरू होगा, और उन्हें प्रत्येक कार्यकर्ता प्रक्रिया में भेज देगा। इसका मतलब है आप स्मृति एक सूची के लिए पूरे iterable परिवर्तित करने की हिट नहीं लेते हैं, लेकिन यह भी मतलब है प्रदर्शन बेडौल की कमी की वजह, बड़े iterables के लिए धीमी है। हालांकि, 1 के डिफ़ॉल्ट से chunksize तर्क पारित करके इसे कम किया जा सकता है।

imap/imap_unordered और map/map_async के बीच अन्य प्रमुख अंतर यह है कि imap/imap_unordered साथ, आप जितनी जल्दी कार्यकर्ताओं से परिणाम प्राप्त करना शुरू कर सकते हैं के रूप में वे तैयार हैं, बल्कि उन सभी के लिए प्रतीक्षा करने के लिए होने के लिए की तुलना में है ख़त्म होना। map_async के साथ, AsyncResult तुरंत लौटा दिया जाता है, लेकिन आप वास्तव में उस ऑब्जेक्ट से परिणाम पुनर्प्राप्त नहीं कर सकते हैं जब तक कि उन सभी को संसाधित नहीं किया जाता है, जिस बिंदु पर यह उसी सूची को लौटाता है जो map करता है (map वास्तव में आंतरिक रूप से map_async(...).get() के रूप में कार्यान्वित किया जाता है)। आंशिक परिणाम प्राप्त करने का कोई तरीका नहीं है; आप या तो पूरा परिणाम, या कुछ भी नहीं है।

imap और imap_unordered दोनों iterables तुरंत वापस जाएँ। imap के साथ, परिणाम, जैसे ही वे तैयार हैं iterable से सामने आए हो जाएगा, जबकि अभी भी इनपुट iterable के आदेश संरक्षण। imap_unordered के साथ, परिणाम जैसे ही वे तैयार हैं, इनपुट iterable के आदेश की परवाह किए बिना झुकेंगे दिया जाएगा।तो, कहते हैं कि तुम यह है:

import multiprocessing 
import time 

def func(x): 
    time.sleep(x) 
    return x + 2 

if __name__ == "__main__":  
    p = multiprocessing.Pool() 
    start = time.time() 
    for x in p.imap(func, [1,5,3]): 
     print("{} (Time elapsed: {}s)".format(x, int(time.time() - start))) 

हो जाएगा ताकि उत्पादन:

3 (Time elapsed: 1s) 
7 (Time elapsed: 5s) 
5 (Time elapsed: 5s) 

आप p.imap के बजाय p.imap_unordered का उपयोग करते हैं, तो आप देखेंगे:

3 (Time elapsed: 1s) 
5 (Time elapsed: 3s) 
7 (Time elapsed: 5s) 

आप का उपयोग करते हैं p.map या p.map_async().get(), आप देखेंगे:

3 (Time elapsed: 5s) 
7 (Time elapsed: 5s) 
5 (Time elapsed: 5s) 

तो, मुख्य कारणों में उपयोग करने के लिए imap/imap_unorderedmap_async अधिक कर रहे हैं:

  1. आपका iterable इतना बड़ा है कि यह एक सूची में कनवर्ट आप/से बाहर चलाने के अत्यधिक स्मृति का उपयोग करने के लिए पैदा होता है।
  2. आप से पहले से पहले परिणामों को संसाधित करना शुरू करना चाहते हैं।
+1

आवेदन और लागू_async के बारे में क्या? –

+6

@ हरशदाफ्टरी 'लागू' एक कार्यकर्ता प्रक्रिया के लिए एक ही कार्य भेजता है, और उसके बाद इसे पूरा होने तक ब्लॉक करता है। 'apply_async' कार्य प्रक्रिया में एक ही कार्य भेजता है, और उसके बाद तुरंत 'AsyncResult' ऑब्जेक्ट देता है, जिसका उपयोग कार्य को समाप्त करने और परिणाम पुनर्प्राप्त करने के लिए प्रतीक्षा करने के लिए किया जा सकता है। 'apply' को 'apply_async (...) पर कॉल करके कार्यान्वित किया जाता है।()' – dano

+0

@dano क्या कोड को संशोधित करना संभव है कि यह टिप्पणियों में निहित सेकंड प्रिंट भी करेगा? धन्यवाद। –

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