มีความแตกต่างที่สำคัญสองอย่างระหว่างimap
/ imap_unordered
และmap
/ map_async
:
- วิธีที่พวกเขาบริโภคมันที่คุณผ่านไป
- วิธีที่พวกเขาส่งคืนผลลัพธ์ให้คุณ
map
กิน iterable ของคุณโดยการแปลง iterable ไปยังรายการ (สมมติว่ามันไม่ได้เป็นรายการแล้ว), Pool
ทำลายมันเป็นชิ้นและส่งชิ้นเหล่านั้นไปยังกระบวนการปฏิบัติงานใน การแบ่ง iterable เป็นชิ้นมีประสิทธิภาพดีกว่าการส่งแต่ละไอเท็มใน iterable ระหว่างการประมวลผลทีละรายการ - โดยเฉพาะถ้า iterable มีขนาดใหญ่ อย่างไรก็ตามการเปลี่ยน iterable เป็นรายการเพื่อให้สามารถมีหน่วยความจำสูงมากเนื่องจากรายการทั้งหมดจะต้องเก็บไว้ในหน่วยความจำ
imap
ไม่เปลี่ยน iterable ที่คุณให้ไว้ในรายการและไม่แบ่งเป็นชิ้น ๆ (ตามค่าเริ่มต้น) มันจะวนซ้ำองค์ประกอบหนึ่งในแต่ละครั้งและส่งพวกเขาไปยังกระบวนการของผู้ปฏิบัติงาน ซึ่งหมายความว่าคุณไม่ต้องใช้หน่วยความจำในการแปลงทั้ง iterable เป็นรายการ แต่ยังหมายถึงประสิทธิภาพจะช้าลงสำหรับ iterables ขนาดใหญ่เนื่องจากการขาดการ chunking อย่างไรก็ตามสิ่งนี้สามารถบรรเทาได้โดยผ่านการchunksize
โต้แย้งมากกว่าค่าเริ่มต้นที่ 1
ข้อแตกต่างที่สำคัญอื่น ๆ ระหว่าง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
ผลลัพธ์จะได้รับทันทีที่พร้อมโดยไม่คำนึงถึงลำดับของอินพุตที่ทำซ้ำได้ ดังนั้นสมมติว่าคุณมีสิ่งนี้:
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
คือ:
- การทำซ้ำของคุณมีขนาดใหญ่พอที่จะแปลงเป็นรายการจะทำให้คุณใช้งาน / ใช้หน่วยความจำมากเกินไป
- คุณต้องการที่จะสามารถที่จะเริ่มต้นการประมวลผลผลก่อนที่ทั้งหมดของพวกเขาจะเสร็จสมบูรณ์