我试图用numpy方式和基本的pythonic方式来衡量评估数学函数所花费的时间。首先,我测量了评估功能所需的时间。
import numpy as np
import scipy as sp
import scipy.integrate as si
def func1(x):
return np.piecewise(x, [x<=2, x>2],
[lambda x: 2*x + pow(2, x),
lambda x: -(pow(x, 2) + 2)]
)
def func2(x):
if (x<=2): return 2*x + pow(2,x)
else: return -(pow(x, 2) + 2)
data = np.linspace(-10, 10, 1000)
%timeit data1 = func1(data)
data2 = []
%timeit for i in range(0, np.size(data)): data2.append(func2(data[i]))
实际上,上面的结果和我预期的一样,numpy方式比基本方式快得多。
35.2 µs ± 110 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
771 µs ± 10.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
然而,在scipy.integrate.quad中发生了奇怪的事情。基本的pythonic方式的集成速度要快得多。为什么会这样?
%timeit si.quad(func1, -10, 10)
%timeit si.quad(func2, -10, 10)
5.59 ms ± 25.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
187 µs ± 39.3 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)
答案 0 :(得分:1)
np.piecewise
才会很快。当输入是标量时,它比python等价物慢得多,可能是由于开销:
from timeit import timeit
kwds = dict(globals=globals(), number=1000)
print(timeit("data1 = func1(data)", **kwds))
data2 = []
print(timeit("for i in range(0, np.size(data)): data2.append(func2(data[i]))", **kwds))
data3 = []
print(timeit("for i in range(0, np.size(data)): data3.append(func1(data[i]))", **kwds))
0.06953751016408205
0.957529284991324
15.591511018108577
现在,它与func2
一起使用的事实,文档和流行的自适应集成方案的工作方式都表明quad
一个接一个地用标量参数调用其被积函数,这可以解释你的观察。