0

我在 python 中有一个脚本,但运行到结束需要 20 多个小时。

由于我的代码很大,我将发布一个简化的代码。

代码的第一部分:

flag = 1
mydic = {}
for i in mylist:
    mydic[flag] = myfunction(i)
    flag += 1

mylist有 700 多个条目,每次我调用myfunction它运行大约 20 秒。

所以,我在想是否可以使用并行编程将迭代分成两组并同时运行。这可能吗?我会比以前需要一半时间吗?

第二部分代码:

mymatrix = []
for n1 in range(0,flag):
    mat = []
    for n2 in range(0,flag):
        if n1 >= n2:
            mat.append(0)
        else:
            res = myfunction2(mydic(n1),mydic(n2))
            mat.append(res)
    mymatrix.append(mat)

所以,如果mylist有 700 个条目,我想创建一个 700x700 的矩阵,它是上三角矩阵。但是myfunction2()每次需要大约30秒。我不知道我是否也可以在这里使用并行编程。

我无法简化myfunction()andmyfunction2()因为它们是我调用外部 api 并返回结果的函数。

您对我如何更改它以使其更快有什么建议吗?

4

2 回答 2

1

根据您的评论,我认为这 30 秒的时间很可能主要是由于外部 API 调用。我会添加一些计时代码来测试您的代码的哪些部分实际上是造成缓慢的原因。

如果是来自外部 API 调用,有一些简单的修复方法。外部 API 调用阻塞,因此如果您可以迁移到并行模型,您将获得加速(尽管 30 秒的阻塞对我来说听起来很大)。

我认为通过将 2 个循环的输出作为要传递给函数的参数矩阵来创建一个快速的“任务列表”是最简单的。然后我会将它们导入Celery以运行任务。这应该可以让您以最少的工作量获得不错的加速。

threading您可能会使用or模块来运行任务(或部分)节省更多时间multiprocessing,甚至将其全部用Twistedpython 编写——但这通常比简单的 celery 函数花费更长的时间。

Celery方法的一个警告是您将分派大量工作 - 因此您必须具有一些功能来轮询结果。这可能是一个while循环,它会不断sleeps(10)重复,直到 celery 对每个任务都有结果。如果您在 中执行此操作Twisted,您可以在完成时访问/跟踪结果。我从来没有用多处理做这样的事情,所以不知道这将如何适应。

于 2013-09-15T16:22:08.990 回答
0

如何在第二部分使用生成器而不是 for 循环之一

def fn():
    for n1 in range(0, flag):
        yield n1

generate = fn()

while True:
    a = next(generate)
    for n2 in range(0, flag):
        if a >= n2:
            mat.append(0)
        else:
            mat.append(myfunction2(mydic(a),mydic(n2))
            mymatrix.append(mat)
于 2013-09-15T15:52:57.290 回答