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

如何在python中并行化大for循环

祖翰音
2023-03-14
问题内容

我刚接触Python,但仍处于学习曲线的艰难阶段。感谢您的任何评论。

我有一个很大的for循环要运行(在许多迭代中都很大),例如:

for i in range(10000)
    for j in range(10000)
        f((i,j))

我虽然认为这将是一个如何并行化的常见问题,但在Google上搜索了数小时后,我使用“多重处理”模块找到了解决方案,如下所示:

pool=Pool()
x=pool.map(f,[(i,j) for i in range(10000) for j in range(10000)])

当循环较小时,此html" target="_blank">方法有效。但是,如果循环很大,这确实很慢,或者如果循环太大,有时会发生内存错误。看来python会首先生成参数列表,然后甚至使用xrange将列表提供给函数“
f”。那是对的吗?

所以这种并行化对我来说不起作用,因为我真的不需要将所有参数都存储在列表中。有一个更好的方法吗?我感谢任何建议或参考。谢谢。


问题答案:

看来python会首先生成参数列表,然后甚至使用xrange将列表提供给函数“ f”。那是对的吗?

是的,因为您使用的是列表推导,它明确要求它生成该列表。

(请注意,xrange这里并没有什么关系,因为一次只能有两个范围,每个范围都是10K;与参数列表的100M相比,没什么。)

如果希望它根据需要动态生成值,而不是一次生成所有100M,则要使用生成器表达式而不是列表推导。几乎总是将括号变成括号的问题:

x=pool.map(f,((i,j) for i in range(10000) for j in range(10000)))

但是,正如您从源代码中看到的那样,map如果您给它提供一个生成器,它最终只会列出一个列表,因此,在这种情况下,它什么也解决不了。(文档没有明确说明这一点,但是很难看到如果没有长度,如何选择合适的块大小将可迭代对象切成小块……)。

而且,即使事实并非如此,您仍然会在结果上再次遇到相同的问题,因为会pool.map返回一个列表。

要解决这两个问题,可以pool.imap改用。它懒惰地消耗可迭代,并返回结果的惰性迭代器。

需要注意的一件事是,imap如果不通过,则不会猜测最佳的块大小,而只是默认为1,因此您可能需要一些思考或反复试验来优化它。

此外,imap仍会在输入结果时将它们排入队列,因此它可以按照参数的顺序将它们反馈给您。在病理情况下,最终可能会导致结果排队(poolsize-1)/
poolsize,尽管实际上这种情况很少见。如果要解决此问题,请使用imap_unordered。如果您需要了解顺序,只需将参数与参数和结果来回传递即可:

args = ((i, j) for i in range(10000) for j in range(10000))
def indexed_f(index, (i, j)):
    return index, f(i, j)
results = pool.imap_unordered(indexed_f, enumerate(args))

但是,我注意到在您的原始代码中,您对的结果根本不做任何事情f(i, j)。在那种情况下,为什么还要费心收集所有结果呢?在这种情况下,您可以返回循环:

for i in range(10000):
    for j in range(10000):
        map.apply_async(f, (i,j))

但是,imap_unordered可能仍然值得使用,因为它提供了一种非常简单的方法来阻止所有任务完成,同时仍保持池本身运行以供以后使用:

def consume(iterator):
    deque(iterator, max_len=0)
x=pool.imap_unordered(f,((i,j) for i in range(10000) for j in range(10000)))
consume(x)


 类似资料:
  • 问题内容: 我正在使用Python的Anaconda发行版以及Numba,并且编写了以下Python函数,该函数将稀疏矩阵 (以CSR格式存储)乘以一个密集向量 : 这 是一个大的稀疏矩阵, 并且 是一个数组。这是调用上述功能的代码片段: 请注意, -decorator告诉Numba对 函数进行即时编译。 在我的实验中,我的功能大约是该方法的 两倍 。对于Numba来说,这是一个非常令人印象深刻的

  • 问题内容: 我一直在尝试并行化以下脚本,特别是for循环。我怎样才能做到这一点? 问题答案: 更换 与

  • 我想在Python2.7中并行化两个嵌套的for循环,但我自己没有成功。我不知道如何接近什么是并行化的定义。 总之,这里是单处理器代码:

  • 我有一个python for循环,它执行一个bash脚本,如下所示(我将其简化为只包含需要显示的内容),我需要它在for循环中同时运行所有这些bash脚本,但要等到它们全部完成后才能继续串联。bash脚本是我唯一希望并行运行的部分。它是在同一for循环的下游做一些需要串联完成的事情。这可能吗? 以下是系列作品。没有脚本的并行执行,因为。如果我删除. etc(),它几乎立即出错,下游的任何东西都不再

  • 我想在一个并行外部循环中运行一个包含for循环(应该并行运行)的函数。因此看起来如下所示: 给定上面的代码,我希望在函数中为循环创建5个并行线程,并且希望这5个线程中的每个线程创建另一个线程来运行自己的并行for循环。

  • 问题内容: 我听说Java 8提供了许多有关并发计算的实用程序。因此,我想知道并行化给定for循环的最简单方法是什么? 问题答案: 在流上阅读,它们都是新的流行。 特别注意并行性: “具有显式for循环的处理元素本质上是串行的。流通过将计算重新格式化为聚合操作的流水线,而不是作为对每个单独元素的命令性操作来促进并行执行。所有流操作都可以串行或并行执行。 ” 综上所述,没有并行的for循环,它们本质