Có hai điểm khác biệt chính giữa imap/ imap_unorderedvà map/ map_async:
- Cách họ tiêu thụ lặp đi lặp lại bạn truyền cho họ.
- Cách họ trả lại kết quả cho bạn.
maptiêu thụ iterable của bạn bằng cách chuyển đổi iterable thành một danh sách (giả sử nó chưa phải là một danh sách), chia nó thành các khối và gửi các khối đó đến các quy trình worker trong Pool. Việc chia iterable thành các khối thực hiện tốt hơn so với việc chuyển từng mục trong lần lặp giữa các tiến trình một mục tại một thời điểm - đặc biệt nếu số lần lặp lớn. Tuy nhiên, biến iterable thành một danh sách để chunk nó có thể có chi phí bộ nhớ rất cao, vì toàn bộ danh sách sẽ cần phải được giữ trong bộ nhớ.
imapkhông biến iterable mà bạn đưa nó thành một danh sách, cũng không biến nó thành các khối (theo mặc định). Nó sẽ lặp đi lặp lại qua từng phần tử lặp và gửi chúng cho mỗi phần tử tới một quy trình worker. Điều này có nghĩa là bạn không sử dụng bộ nhớ để chuyển đổi toàn bộ lần lặp thành một danh sách, nhưng điều đó cũng có nghĩa là hiệu suất chậm hơn đối với các lần lặp lớn, vì thiếu đoạn mã. Điều này có thể được giảm thiểu bằng cách chuyển một chunksizeđối số lớn hơn mặc định là 1, tuy nhiên.
Sự khác biệt lớn khác giữa imap/ imap_unorderedvà map/ map_async, là với imap/ imap_unordered, bạn có thể bắt đầu nhận kết quả từ nhân viên ngay khi họ sẵn sàng, thay vì phải đợi tất cả trong số họ kết thúc. Với map_async, một AsyncResulttrả về ngay lập tức, nhưng bạn thực sự không thể lấy kết quả từ đối tượng đó cho đến khi tất cả chúng được xử lý, tại đó nó trả về cùng một danh sách map( mapthực tế được thực hiện như trong map_async(...).get()). Không có cách nào để có được kết quả một phần; bạn có toàn bộ kết quả, hoặc không có gì.
imapvà imap_unorderedcả hai trả lại iterables ngay lập tức. Với imap, kết quả sẽ được mang lại từ lần lặp ngay khi chúng sẵn sàng, trong khi vẫn duy trì thứ tự của lần lặp đầu vào. Với imap_unordered, kết quả sẽ được mang lại ngay khi chúng sẵn sàng, bất kể thứ tự lặp lại đầu vào. Vì vậy, nói rằng bạn có điều này:
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)))
Điều này sẽ xuất ra:
3 (Time elapsed: 1s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)
Nếu bạn sử dụng p.imap_unorderedthay vì p.imap, bạn sẽ thấy:
3 (Time elapsed: 1s)
5 (Time elapsed: 3s)
7 (Time elapsed: 5s)
Nếu bạn sử dụng p.maphoặc p.map_async().get(), bạn sẽ thấy:
3 (Time elapsed: 5s)
7 (Time elapsed: 5s)
5 (Time elapsed: 5s)
Vì vậy, lý do chính để sử dụng imap/ imap_unorderedhơn map_asynclà:
- Lặp lại của bạn đủ lớn để chuyển đổi nó thành một danh sách sẽ khiến bạn hết / sử dụng quá nhiều bộ nhớ.
- Bạn muốn có thể bắt đầu xử lý kết quả trước khi hoàn thành tất cả chúng.