Python 来自concurrent.futures的ProcessPoolExecutor比multiprocessing.Pool慢

Python 来自concurrent.futures的ProcessPoolExecutor比multiprocessing.Pool慢,python,concurrency,multiprocessing,future,concurrent.futures,Python,Concurrency,Multiprocessing,Future,Concurrent.futures,我在试验Python3.2中引入的新的闪亮模块,我注意到,使用几乎相同的代码,从concurrent.futures使用池要比使用慢得多 这是使用多处理的版本: def hard_work(n): # Real hard work here pass if __name__ == '__main__': from multiprocessing import Pool, cpu_count try: workers = cpu_count()

我在试验Python3.2中引入的新的闪亮模块,我注意到,使用几乎相同的代码,从concurrent.futures使用池要比使用慢得多

这是使用多处理的版本:

def hard_work(n):
    # Real hard work here
    pass

if __name__ == '__main__':
    from multiprocessing import Pool, cpu_count

    try:
        workers = cpu_count()
    except NotImplementedError:
        workers = 1
    pool = Pool(processes=workers)
    result = pool.map(hard_work, range(100, 1000000))
这是使用concurrent.futures:

def hard_work(n):
    # Real hard work here
    pass

if __name__ == '__main__':
    from concurrent.futures import ProcessPoolExecutor, wait
    from multiprocessing import cpu_count
    try:
        workers = cpu_count()
    except NotImplementedError:
        workers = 1
    pool = ProcessPoolExecutor(max_workers=workers)
    result = pool.map(hard_work, range(100, 1000000))
使用从中提取的天真因子分解函数,以下是我的计算机(i7,64位,Arch Linux)上的结果:


我无法使用Python分析器分析这些,因为我会遇到pickle错误。有什么想法吗?

当使用
映射
from
concurrent.futures
时,从iterable到executor的每个元素都会为每个调用创建一个对象。然后,它返回一个迭代器,该迭代器将生成futures返回的结果。
对象是相当重的,它们做了大量的工作来允许它们提供的所有功能(如回调、取消功能、检查状态等等)

相比之下,
multiprocessing.Pool
的开销要少得多。它批量提交作业(减少IPC开销),并直接使用函数返回的结果。对于大批量作业,多处理无疑是更好的选择

如果您希望在开销不太重要的情况下使用长时间运行的作业,并且希望通过回调或不时检查来获得通知,以查看这些作业是否已完成,或者是否能够单独取消执行,则未来是非常好的

个人说明:


我真的想不出有多少理由使用
Executor.map
——它没有给你任何期货的功能——除了指定超时的功能。如果您只是对结果感兴趣,最好使用
多处理.Pool
的映射函数之一。

非常感谢您的回答!批量提交可能是这里的关键。值得一提的是,在Python 3.5中,
ProcessPoolExecutor.map
将接受
chunksize
关键字参数,这将在一定程度上缓解IPC开销问题。有关更多信息,请参见本文。此外,在Python3.2中,您可以为多进程池设置maxtasksperchild,在我的例子中,它有助于在每个工作人员完成其工作负载后清理资源。我更喜欢
ProcessPoolExecutor.map()
,因为在
mp.Pool.map()
中,似乎@Ciprian提到的bug仍然存在,并且有一些未完成的尝试来修复它,最新的一个是你能发布更新吗?也许是3.8版?
[juanlu@nebulae]─[~/Development/Python/test]
└[10:31:10] $ time python pool_multiprocessing.py 

real    0m10.330s
user    1m13.430s
sys 0m0.260s
[juanlu@nebulae]─[~/Development/Python/test]
└[10:31:29] $ time python pool_futures.py 

real    4m3.939s
user    6m33.297s
sys 0m54.853s