首页 > 解决方案 > python:使用相同参数有效调用多个函数(返回布尔值)

问题描述

我试图找到调用多个函数的最佳方法,每个函数都需要相同的参数,每个函数都以最有效的方式返回一个布尔值。

def A(x):
    ....
    return x > 2

def B(x):
    ....
    return x < 10

def C(x):
    ....
    return x > 5

list_of_functions = [A, B, C]
result = [fun(x) for fun in list_of_functions]

有什么更好的我可以在这里做的吗?另外,我可以应用一些多处理,它会使其更快一点吗?

标签: pythonmultithreadingmultiprocessing

解决方案


首先,这在很大程度上取决于您尝试做的实际工作。现在:

有什么更好的我可以在这里做的吗?

看起来不像。您的解决方案似乎很简单,我个人想不出更有创意的方法。至于多处理,我们将在接下来看到。

我可以应用一些多处理吗?

嗯,是。几乎任何事情。一种方法是使用multiprocessing's Pool,使工作函数是一个高阶函数,它对函数列表进行操作,并在静态参数上运行每个函数。因此,例如,您可以使用以下map方法:

from multiprocessing import Pool

x = 5

def worker(func):
    return func(x)

def parallel():
    with Pool() as pool:
        return pool.map(worker, list_of_functions)

它会让它快一点吗?

所以正如我一开始所说,这在很大程度上取决于你的实际工作。非常快速的功能不会从多处理中受益,因为开销会超过好处。一个简单的演示:

我以您的示例为例,并以两种操作方式按原样运行(最简单的功能):

from timeit import timeit
from multiprocessing import Pool

x = 5

def A(x):
    return x > 2

def B(x):
    return x < 10

def C(x):
    return x > 5

def linear():
    return [fun(x) for fun in list_of_functions]

def worker(func):
    return func(x)

def parallel():
    with Pool() as pool:
        return pool.map(worker, list_of_functions)

list_of_functions = [A, B, C]

if __name__ == "__main__":
    print(f"linear running time: {timeit(linear, number=10)}")
    print(f"parallel running time: {timeit(parallel, number=10)}")

定时给出:

linear running time: 9.569999999992085e-05
parallel running time: 7.2561405

您可以看到并行版本的速度非常慢。减少差距的一种方法是使用线程而不是开销稍低的进程。这是通过更改导入语句以使用dummy版本来完成的:

from multiprocessing.dummy import Pool

这现在给出:

linear running time: 4.3600000000143524e-05
parallel running time: 1.0739620000000003

现在,当增加一些复杂性时,您可以开始看到不同之处。由于我不是很有创意,我只是在函数中添加了一个增量循环:

def A(x):
    for i in range(1000000):
        x += 1
    return x > 2

def B(x):
    for i in range(1000000):
        x += 1
    return x < 10

def C(x):
    for i in range(1000000):
        x += 1
    return x > 5

现在结果是:

linear running time: 13.4436189
parallel running time: 10.7856389

我们仍然可以看到大约 7 秒的几乎恒定开销,因为我们预计并行版本的时间是线性版本的三分之一(同时运行 3 个函数)。


在四核 i7 上使用 Windows10 运行 Python 3.7.3


推荐阅读