Python:并行化任何/所有语句

时间:2015-04-14 17:11:05

标签: python performance parallel-processing

我正在运行一些Python程序,而且我注意到瓶颈在于执行以下操作

all(foo(s) for s in l)

我想知道的是 - 将这个变成并行计算的最佳方法是什么? foo(s)是一个线程安全的方法,检查s并根据某些标准返回True / False。 foo没有改变任何数据结构。

所以问题是

  

如果列表的所有元素都具有属性foo,如何并行测试   ,只要l的一个元素不满足foo就退出?

编辑。添加更多上下文。我不知道你在寻找什么样的上下文,但在我的场景中,s是一个图形,foo(s)计算一些图形理论不变量(例如平均距离或类似的东西)

2 个答案:

答案 0 :(得分:3)

这取决于foo(s)正在做什么。如果是I / O绑定,等待阻塞调用,而不仅仅是使用线程将有所帮助。最简单的方法是创建一个线程池并使用pool.map

from multiprocessing.pool import ThreadPool
pool = ThreadPool(10)
all(pool.map(foo, l))

但是,如果函数是cpu绑定的,使用大量处理器电源,这对你没有帮助。相反,您需要使用多处理池:

from multiprocessing import Pool
pool = Pool(4)
all(pool.map(foo, l))

这将使用单独的进程而不是线程,允许使用多个cpu内核。但是,如果您的函数foo非常快,则开销将消除并行处理的任何优势,因此您需要进行测试以确保获得预期的结果

请参阅:https://docs.python.org/2/library/multiprocessing.html#using-a-pool-of-workers

修改 我假设你使用的是Python 2.7.x.如果您使用的是Python3,则concurrent.futures中有更高级的并发功能。包括ThreadPoolExecutorProcessPoolExecutor

我建议使用那些进行并行处理,使用asyncio lib来解决I / O问题。

答案 1 :(得分:0)

Python附带multiprocessing模块;有example实现经典reduce算法(可用于实现all)。通常,您可能希望查看Pool功能:

  

Pool类表示工作进程池。它有一些方法允许以几种不同的方式将任务卸载到工作进程。