我正在运行一些Python程序,而且我注意到瓶颈在于执行以下操作
all(foo(s) for s in l)
我想知道的是 - 将这个变成并行计算的最佳方法是什么? foo(s)是一个线程安全的方法,检查s并根据某些标准返回True / False。 foo没有改变任何数据结构。
所以问题是
如果列表的所有元素都具有属性foo,如何并行测试 ,只要l的一个元素不满足foo就退出?
编辑。添加更多上下文。我不知道你在寻找什么样的上下文,但在我的场景中,s是一个图形,foo(s)计算一些图形理论不变量(例如平均距离或类似的东西)
答案 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中有更高级的并发功能。包括ThreadPoolExecutor
和ProcessPoolExecutor
。
我建议使用那些进行并行处理,使用asyncio lib来解决I / O问题。
答案 1 :(得分:0)