python - 更快地调用函数求值

标签 python performance function numpy optimization

我有一个函数需要至少评估 1e6 次。它只需要两个数组作为输入。

import numpy as np
np.random.seed(1)

res = np.random.rand(0,1,1000)
f1 = lambda r, sig: -0.5*(np.sum(2*np.log(sig) + np.log(2*np.pi) + (r/sig)**2))    

目前,

%timeit f1(res,np.sqrt(res)) 

时钟频率为 26 usc。有什么方法可以让我获得更快的评估调用/执行时间?

任何手段都可以;例如不使用 lambda 函数,使用 native 数学而不是 numpy,或任何涉及使用 Python 中实现的更快数学运算来操作方程的技巧。

编辑:

我犯了一个愚蠢的错误,生成了一个空的 res 数组。所以应该是这样

res=np.random.rand(1000)

此外,第二个数组np.sqrt(res)实际上独立于res,并且通常由比res小得多的值组成,但我使用 sqrt(res) 只是为了说明。

所以重写代码更清晰

import numpy as np
np.random.seed(1)

res1 = np.random.rand(1000)
res2 = np.sqrt(res) #not true in general but res2<res1
f1 = lambda r, sig: -0.5*(np.sum(2*np.log(sig) + np.log(2*np.pi) + (r/sig)**2)) 

现在 %f1(res1,res2) 在我的机器上以 60 usec 计时。

最佳答案

供引用,f1您定义的方式给了我:

10000 loops, best of 3: 20.9 µs per loop

一个简单的优化,以避免每次都计算np.log(2*np.pi):

log2pi = np.log(2*np.pi)
f2 = lambda r, sig: -0.5*(np.sum(2*np.log(sig) + log2pi + (r/sig)**2))

这将我的 timeit 输出减少了大约 15%:

100000 loops, best of 3: 17.8 µs per loop

此外,计算 x*x 通常比计算 x**2 更快。通过这种方法,您也可以避免 2* 操作。

def f3(r, sig):
   sig2 = sig * sig
   return -0.5*(np.sum(np.log(sig2) + log2pi + (r*r/sig2)))

100000 loops, best of 3: 15 µs per loop

此外,根据您使用参数 res, np.sqrt(res) 调用此函数的频率,您绝对可以考虑将其简化为:

f4 = lambda a: -0.5*np.sum(np.log(a) + log2pi + a)

您可以检查 f4(res) == f1(res, np.sqrt(res)) 并且它的运行速度也显着加快(大约 44%)。

100000 loops, best of 3: 11.7 µs per loop

关于python - 更快地调用函数求值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47366872/

相关文章:

python - 在这种特殊情况下,哪个内置函数应该首先出现?

Python 连接组件边列表

c - 通过c中的函数传递文件

linux - 为什么编译后.o文件中的函数名与.cc文件中的函数名不同?

java - 在 O(n log n) 时间内生成长度为 n 且反转次数为 k 的数组的算法?

python - 初始化类定义的可选变量,其默认值与实例变量相同

python - 如何使用多处理将函数应用于二维 numpy 数组

python - 如何将字典列表转换为单个 Pandas 数据框?

c++ - 为什么插入 set<vector<string>> 这么慢?

java - 一个简单的 Java2D 应用程序的可怕性能