वहाँ imap
/imap_unordered
और map
/map_async
के बीच दो प्रमुख अंतर हैं:
- तरह वे iterable आप उन्हें पारित खपत करते हैं।
- जिस तरह से वे परिणाम आपको वापस लौटते हैं।
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_unordered
map_async
अधिक कर रहे हैं:
- आपका iterable इतना बड़ा है कि यह एक सूची में कनवर्ट आप/से बाहर चलाने के अत्यधिक स्मृति का उपयोग करने के लिए पैदा होता है।
- आप से पहले से पहले परिणामों को संसाधित करना शुरू करना चाहते हैं।
आवेदन और लागू_async के बारे में क्या? –
@ हरशदाफ्टरी 'लागू' एक कार्यकर्ता प्रक्रिया के लिए एक ही कार्य भेजता है, और उसके बाद इसे पूरा होने तक ब्लॉक करता है। 'apply_async' कार्य प्रक्रिया में एक ही कार्य भेजता है, और उसके बाद तुरंत 'AsyncResult' ऑब्जेक्ट देता है, जिसका उपयोग कार्य को समाप्त करने और परिणाम पुनर्प्राप्त करने के लिए प्रतीक्षा करने के लिए किया जा सकता है। 'apply' को 'apply_async (...) पर कॉल करके कार्यान्वित किया जाता है।()' – dano
@dano क्या कोड को संशोधित करना संभव है कि यह टिप्पणियों में निहित सेकंड प्रिंट भी करेगा? धन्यवाद। –