如何使用 python 在循环中高效地调用函数?
How can I efficiently call a function in a loop with python?
我正在求解一个随机微分方程,并且我有一个包含求解该方程的算法的函数。所以我必须在每个时间步调用该函数(它类似于 Runge Kutta 的方法但有一个随机变量),然后我必须多次求解方程(因为解是随机的)以便能够对所有解决方案。这就是为什么我想知道如何以最有效的方式在每次迭代中调用此函数。
如果您正在使用 for
循环和 range()
,并且不会使用每次迭代附带的数字,您可以使用下划线来节省一些效率:
for _ in range(100):
print("Function call")
如果只在循环中使用函数,可以直接传入正在使用的函数的内容,省去函数的定义,节省一些效率。
在可迭代对象上实现函数的最佳方法是使用 map
函数。
由于 map
是用 C 编写的并且经过高度优化,其内部隐含循环比常规 Python for 循环更有效。
根据您的使用情况,使用 itertools.starmap()
可能更有利。您可以将 starmap()
视为 , multi-variable implementation of map()
. You can find more information on it here。它的行为大致相当于:
def starmap(function, iterable):
# starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
for args in iterable:
yield function(*args)
所以你可以像这样使用它:
from itertools import starmap
def myAddNumbers(a,b):
return a+b
myListOfArgTuples = [(1,2), (3,4), (5,6)]
cosmicCartograph = starmap(myAddNumbers, myListOfArgs)
请注意,starmap()
returns 是一个生成器对象,因此为了“执行”生成器,您需要实例化它:
myResultsList = list(cosmicCartograph)
# [3, 7, 11]
或
myResultsSummed = sum(cosmicCartograph)
# 21
优化函数调用的一些方法:
- 如果函数参数和结果始终相同,则将函数调用移出循环
- 如果某些函数参数重复并且给定参数集的结果相同,请使用 memoize 或 lru_cache
但是,既然您说您的应用程序是 Runge-Kutta 的变体,那么这些都不太可能起作用;您将拥有不同的 t 值和建模状态向量,因此您 必须 在循环中调用该函数,并且值不断变化。
如果您的算法很慢,那么调用函数的效率再高也无济于事。查看优化函数以使其 运行 更快(或转换为 Cython)——实际调用本身不是瓶颈。
编辑:我看到您多次 运行 宁此,以确定给定此模拟的随机性质的值范围。在这种情况下,您应该使用多处理 运行 在单独的 CPU 内核上进行多次模拟 - 这会加快速度。
我正在求解一个随机微分方程,并且我有一个包含求解该方程的算法的函数。所以我必须在每个时间步调用该函数(它类似于 Runge Kutta 的方法但有一个随机变量),然后我必须多次求解方程(因为解是随机的)以便能够对所有解决方案。这就是为什么我想知道如何以最有效的方式在每次迭代中调用此函数。
如果您正在使用 for
循环和 range()
,并且不会使用每次迭代附带的数字,您可以使用下划线来节省一些效率:
for _ in range(100):
print("Function call")
如果只在循环中使用函数,可以直接传入正在使用的函数的内容,省去函数的定义,节省一些效率。
在可迭代对象上实现函数的最佳方法是使用 map
函数。
由于 map
是用 C 编写的并且经过高度优化,其内部隐含循环比常规 Python for 循环更有效。
根据您的使用情况,使用 itertools.starmap()
可能更有利。您可以将 starmap()
视为 map()
. You can find more information on it here。它的行为大致相当于:
def starmap(function, iterable):
# starmap(pow, [(2,5), (3,2), (10,3)]) --> 32 9 1000
for args in iterable:
yield function(*args)
所以你可以像这样使用它:
from itertools import starmap
def myAddNumbers(a,b):
return a+b
myListOfArgTuples = [(1,2), (3,4), (5,6)]
cosmicCartograph = starmap(myAddNumbers, myListOfArgs)
请注意,starmap()
returns 是一个生成器对象,因此为了“执行”生成器,您需要实例化它:
myResultsList = list(cosmicCartograph)
# [3, 7, 11]
或
myResultsSummed = sum(cosmicCartograph)
# 21
优化函数调用的一些方法:
- 如果函数参数和结果始终相同,则将函数调用移出循环
- 如果某些函数参数重复并且给定参数集的结果相同,请使用 memoize 或 lru_cache
但是,既然您说您的应用程序是 Runge-Kutta 的变体,那么这些都不太可能起作用;您将拥有不同的 t 值和建模状态向量,因此您 必须 在循环中调用该函数,并且值不断变化。
如果您的算法很慢,那么调用函数的效率再高也无济于事。查看优化函数以使其 运行 更快(或转换为 Cython)——实际调用本身不是瓶颈。
编辑:我看到您多次 运行 宁此,以确定给定此模拟的随机性质的值范围。在这种情况下,您应该使用多处理 运行 在单独的 CPU 内核上进行多次模拟 - 这会加快速度。