मल्टीप्रोसेसिंग। मूल: Map_async और imap के बीच क्या अंतर है?


182

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

क्या मुझे ऐसा कुछ इस्तेमाल करना चाहिए?

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

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

जवाबों:


490

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

  1. जिस तरह से वे आपके द्वारा पास किए जाने वाले चलने योग्य का उपभोग करते हैं।
  2. जिस तरह से वे परिणाम वापस आपके पास लौटाते हैं।

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

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

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

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

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_unorderedइसके बजाय उपयोग करते हैं p.imap, तो आप देखेंगे:

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_unorderedअधिक map_asyncहैं:

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

1
आवेदन और apply_async के बारे में क्या?
हर्ष दफ्तरी

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

51
यह उस तरह का विवरण है जो मौजूदा सुस्त केPool बजाय आधिकारिक दस्तावेज में होना चाहिए ।
मिनट

@dano मैं पृष्ठभूमि में एक फ़ंक्शन चलाना चाहता हूं, लेकिन मेरे पास कुछ संसाधन सीमाएं हैं और फ़ंक्शन को कई बार नहीं चलाया जा सकता है जो मैं चाहता हूं और फ़ंक्शन के अतिरिक्त निष्पादन को पंक्तिबद्ध करना चाहता हूं। क्या आपके पास कोई विचार है कि मुझे यह कैसे करना चाहिए? मेरा सवाल यहाँ है । क्या आप कृपया मेरे प्रश्न पर एक नज़र डाल सकते हैं और देख सकते हैं कि क्या आप मुझे कुछ संकेत (या बेहतर, एक उत्तर) दे सकते हैं कि मुझे यह कैसे करना चाहिए?
अमीर

1
@ बॉलपॉइंट यह काम पूरा होते ही अगले काम पर चला जाएगा। आदेश को मूल प्रक्रिया में वापस संभाला जाता है।
डैनो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.