Python 为什么矢量化计算比for循环等效计算慢
我有两个代码来计算一个函数。一个基于python for循环,如下所示:Python 为什么矢量化计算比for循环等效计算慢,python,python-3.x,performance,numpy,numba,Python,Python 3.x,Performance,Numpy,Numba,我有两个代码来计算一个函数。一个基于python for循环,如下所示: @nb.autojit() def ODEfunction(r): tic = time.process_time() NP=10 s=1 l=100 f = np.zeros(len(r)) lbound=-4* (12*s**12/(-0.5*l-r[0])**13-6*s**6/(-0.5*l-r[0])**7) rbound=-4* (12*s**12/(0.
@nb.autojit()
def ODEfunction(r):
tic = time.process_time()
NP=10
s=1
l=100
f = np.zeros(len(r))
lbound=-4* (12*s**12/(-0.5*l-r[0])**13-6*s**6/(-0.5*l-r[0])**7)
rbound=-4* (12*s**12/(0.5*l-r[NP-1])**13-6*s**6/(0.5*l-r[NP-1])**7)
f[0:NP]=r[NP:2*NP]
for i in range(NP):
fi = 0.0
for j in range(NP):
if (j!=i):
fij = -4*(12*s**12/(r[j]-r[i])**13-6*s**6/(r[j]-r[i]) ** 7)
fi = fi + fij
f[i+NP]=fi
f[NP]=f[NP]+lbound
f[2*NP-1]=f[2*NP-1]+rbound
toc = time.process_time()
print(toc-tic)
return f
另一个是此代码的等效矢量化版本:
@nb.autojit()
def ODEfunction(r):
tic=time.process_time()
NP=10
s=1
l=100
f = np.zeros(len(r))
lbound=-4* (12*s**12/(-0.5*l-r[0])**13-6*s**6/(-0.5*l-r[0])**7)
rbound=-4* (12*s**12/(0.5*l-r[NP-1])**13-6*s**6/(0.5*l-r[NP-1])**7)
f[0:NP]=r[NP:2*NP]
ri=r[0:NP]
rj = r[0:NP]
rij=np.subtract.outer(rj,ri)
fij = -4 * (12 * s ** 12 / (rij) ** 13 - 6 * s ** 6 / (rij) ** 7)
fij[np.diag_indices(NP)]=0
f[NP:2*NP] = fij.sum(axis=0)
f[NP]=f[NP]+lbound
f[2*NP-1]=f[2*NP-1]+rbound
toc=time.process_time()
print(toc-tic)
return f
在这两种情况下,输入r都是一个numpy 1 x 20数组,正如您所看到的,我使用numba来加速代码。令人惊讶的是,在这种情况下,矢量化代码比for循环慢5倍。我以前在这里的一些帖子中也看到过类似的问题:
然而,存在的问题是阵列的巨大规模。正如你在我的例子中看到的,没有涉及任何大数组。有人知道原因和解决方法吗?为什么写数值计算的人总是把代码装得像买不起空白一样?你的测量是无用的。。。删除
time。从那里处理\u time
计算,并使用timeit
模块多次运行函数。此函数是较大代码的一部分,因此在我运行整个代码时,它会运行多次。不管怎样,差别是如此明显,我甚至不需要这些测量。通过使用智能手机的秒表,我可以看出两者的区别。您使用的是numba
?如果是这样,标签和文本中应该清楚numba
可以加快迭代代码的速度。通常关于矢量化的“规则”不适用。@ReblochonMasque,因为将带有许多空格的数字代码发送给合作者要花很长时间?