小编典典

multiprocessing.Pool:map_async 和 imap 有什么区别?

all

我正在尝试学习如何使用 Python 的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

阅读 69

收藏
2022-05-27

共1个答案

小编典典

imap/imap_unorderedmap/之间有两个主要区别map_async

  1. 他们使用您传递给他们的可迭代对象的方式。
  2. 他们将结果返回给您的方式。

map通过将可迭代对象转换为列表(假设它还不是列表)、将其分成块并将这些块发送到Pool. 将 iterable 分成块比在进程之间一次传递一个
item 的 iterable 中的每个项目执行得更好 - 特别是在 iterable
很大的情况下。但是,将可迭代对象转换为列表以对其进行分块可能会产生非常高的内存成本,因为整个列表都需要保存在内存中。

imap不会将您提供的可迭代对象变成列表,也不会将其分成块(默认情况下)。它将一次迭代一个可迭代的元素,并将它们每个发送到一个工作进程。这意味着您不会将整个可迭代对象转换为列表而对内存造成影响,但这也意味着大型可迭代对象的性能较慢,因为缺少分块。然而,这可以通过传递一个chunksize大于默认值
1 的参数来缓解。

imap/imap_unorderedmap/之间的另一个主要区别map_async是,使用imap/
imap_unordered,您可以在工作人员准备好后立即开始接收结果,而不必等待所有工作人员完成。使用map_async
anAsyncResult会立即返回,但在所有结果都已处理之前,您实际上无法从该对象中检索结果,此时它返回与执行相同的列表mapmap实际上在内部实现为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.mapor p.map_async().get(),你会看到:

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

imap因此,使用/ imap_unorderedover的主要原因map_async是:

  1. 您的可迭代对象足够大,以至于将其转换为列表会导致您耗尽/使用太多内存。
  2. 您希望能够在 所有 结果完成之前开始处理结果。
2022-05-27