python - 来自 concurrent.futures 的 ProcessPoolExecutor 比 multiprocessing.Pool 慢

标签 python concurrency multiprocessing future concurrent.futures

我正在试验新的 Shiny concurrent.futures Python 3.2 中引入的模块,我注意到,几乎使用相同的代码,使用 concurrent.futures 中的 Pool 比使用 multiprocessing.Pool方式 .

这是使用多处理的版本:

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))

使用取自 Eli Bendersky article 的简单分解函数,这些是我电脑上的结果(i7, 64-bit, Arch Linux):

[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

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

最佳答案

当使用 concurrent.futures 中的 map 时,每个元素都来自可迭代的 is submitted separately到执行器,它会创建一个 Future每次调用的对象。然后它返回一个迭代器,该迭代器产生 future 返回的结果。
Future对象是相当重量级的,它们做了很多工作来允许它们提供的所有功能(如回调、取消能力、检查状态......)。

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

如果您想汇总长期运行的作业,而开销并不那么重要,您希望通过回调收到通知或不时检查它们是否已完成或能够取消单独执行。

个人笔记:

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

关于python - 来自 concurrent.futures 的 ProcessPoolExecutor 比 multiprocessing.Pool 慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18671528/

相关文章:

c# - 最佳 TPL 数据流设计?

python - 同时训练两个模型

python - 全局变量增量和python多处理

python - 在 Django 中测试外部 URL

python - 更新 python 构造函数中的 fct

python - 如何使用每小时值和日期时间索引将宽格式转换为长格式?

c++ - WinOS 上的线程 sleep 和唤醒

python - 如何在 PyCharm 中设置运行配置的默认工作目录

java - 等待 Java 线程池中的线程子集

list - 如何在PyTorch多处理中共享张量列表?