当前位置: 首页 > 面试题库 >

parallel.futures中的ProcessPoolExecutor比multiprocessing.Pool慢

方光华
2023-03-14
问题内容

我是用新的闪亮试验concurrent.futures在Python
3.2模块引起,而我注意到,几乎相同的代码,使用泳池从concurrent.futures的 方式
比使用慢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))

这是使用current.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文章中获得的简单分解函数,这些就是我计算机(i7、64位,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探查器对它们进行探查,因为出现泡菜错误。有任何想法吗?


问题答案:

使用mapfrom时concurrent.futures,来自iterable的每个元素将分别提交给执行程序,该执行程序Future将为每个调用创建一个对象。然后,它返回一个迭代器,该迭代器产生期货返回的结果。
Future对象相当重,它们需要做很多工作才能允许它们提供的所有功能(例如回调,取消功能,检查状态等)。

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

如果您希望对那些开销不那么重要的长期运行的工作进行汇总,希望通过回调通知您或不时检查它们是否完成或能够单独取消执行,则期货是很好的选择。

个人说明

我真的想不出使用什么理由Executor.map-它没有提供任何期货功能-
除了可以指定超时的功能。如果您只是对结果感兴趣,最好使用multiprocessing.Pool的map函数之一。



 类似资料:
  • 问题内容: (这个问题是关于如何使multiprocessing.Pool()运行代码更快。我终于解决了它,最终的解决方案可以在文章的底部找到。) 原始问题: 我正在尝试使用Python将一个单词与列表中的其他单词进行比较,并检索最相似的列表。为此,我使用了difflib.get_close_matches函数。我正在使用Python 2.6.5的相对较新且功能强大的Windows 7便携式计算机

  • 问题内容: 我正在尝试以这种方式使用python的多处理程序包: 从池的进程中,我要避免等待等待60多个返回结果的进程。那可能吗? 问题答案: 这是一种无需更改功能即可执行此操作的方法。需要两个步骤: 使用您可以传递的选项来确保每次执行任务后重新启动池中的工作进程。 将现有的辅助函数包装在另一个函数中,该函数将调用守护程序线程,然后等待该线程的结果数秒钟。使用守护程序线程很重要,因为进程在退出之前

  • 问题内容: 我打算在我的代码中使用以获得更好的性能。 但是,出现以下错误: 我尝试了另一种方式,并收到此错误: 我的代码如下所示: 我认为由于未在main函数中使用而引起了错误。 我的猜想对吗?以及如何修改代码以修复错误? 问题答案: 问题是您在实例中有一个无法拾取的实例变量()。因为您正在调用实例方法,并且您正在Windows上运行,所以整个实例都必须是可腌制的,才能将其传递给子进程。是一个打开

  • 问题内容: 在创建所需的实际应用程序之前,我试图对此有一个基本的了解。我最近从2.7移到了3.3。 从python文档直接复制粘贴此代码失败,这里的一个简单示例也是如此。 这是我的代码,从第二个示例派生而来: 这是输出: 如何使此代码按预期工作?我希望这些示例可以立即使用。 问题答案: 这是我的错,有两个原因: 该代码不受保护,即没有 看起来奇怪的Traceback是因为未保存文件。以前从没给我造

  • 我有一个关于compareTo函数如何帮助比较器排序的问题,即o1。比较(o2)与o2。比较(o1) 如果两个字符串相等,则此方法返回0,否则返回正值或负值。如果第一个字符串在词典上大于第二个字符串,则结果为正,否则结果为负。 上面的陈述很简单,但是为什么o1.compare(o2)会给我一个升序,而o2.compare(o1)给了我一个降序? 如果我有整数值“5,10,3”,我得到3,5,10和

  • 问题内容: 我还没有看到关于,和用例的清晰示例。我主要使用; 别人的优势是什么? 问题答案: 在Python的早期,要使用任意参数调用函数,可以使用: apply在Python2.7中仍然存在,尽管在Python3中却不存在,并且通常不再使用。如今, 是首选。这些模块尝试提供类似的接口。 Pool.apply就像Python一样apply,除了函数调用是在单独的进程中执行的。Pool.apply直