Python 来自concurrent.futures的ProcessPoolExecutor比multiprocessing.Pool慢
我在试验Python3.2中引入的新的闪亮模块,我注意到,使用几乎相同的代码,从concurrent.futures使用池要比使用慢得多 这是使用多处理的版本: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()
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错误。有什么想法吗?当使用
映射fromconcurrent.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