Python for循环每次迭代变慢
我正在尝试优化一些Python代码(为了加快一些矩阵运算),我的代码大概是这样的(我的真实数据集也类似于'gps'),
import numpy as np
gps = [np.random.rand(50,50) for i in xrange(1000)]
ips = np.zeros( (len(gps),len(gps)), dtype='float32')
for i in xrange(len(gps)):
for j in xrange(0,i+1):
ips[i,j]= f.innerProd(gps[i],gps[j])
ips[j,i]= ips[i,j]
print "Inner product matrix: %3.0f %% done (%d of %d)"% \
(((i+1)**2.)/(len(gps)**2.)*100, i, len(gps))
def innerProd(mat1,mat2):
return float(np.sum(np.dot(np.dot(mat1,mat2),mat1)))
我想了解的是,为什么程序在前几次运行时速度很快,但随着迭代的进行,速度却变慢了?我知道这个问题可能有点幼稚,但我真的想在尝试其他方法之前,先搞清楚发生了什么。我已经在Fortran中实现了我的函数(在Fortran中不使用任何for循环),并使用f2py创建了一个动态库,以便从Python调用这个函数,这就是我在Python中的新代码..
import numpy as np
import myfortranInnProd as fip
gps = [np.random.rand(50,50) for i in xrange(1000)]
ips = np.zeros( (len(gps),len(gps)), dtype='float32')
ips = fip.innerProd(gps)
不幸的是,我发现(令人惊讶的是)我的Fortran-Python版本运行速度比第一版慢了1.5到2倍(重要的是,我在Fortran实现中使用了MATMUL())。我在网上查了很久,我认为这种“变慢”可能与内存带宽、内存分配或缓存有关,因为数据集很大,但我不太确定背后到底发生了什么,以及我该如何提高性能。我在一台小型的Intel Atom(2GB内存)和一台4核的Intel Xeon(8GB内存)上运行了代码(当然数据集也相应缩放),但“变慢”的现象是一样的。
我只想明白为什么会出现这种“变慢”?如果我用C语言实现这个函数会有帮助吗?或者尝试让它在GPU上运行?还有其他提高性能的想法吗?谢谢!
2 个回答
内层的 for
循环执行的次数是根据外层 for
循环的索引 i
的值来决定的。因为你每次内层循环结束时都会显示调试信息,所以随着 i
的增大,这些调试信息显示的次数会越来越少。不过,值得注意的是,显示的百分比是会规律性增加的。
说得简单点,每次你完成外层循环的执行,内层循环的执行次数都会增加。当 i
是 0 的时候,内层循环只会执行一次,但当 i
达到 100 的时候,它会执行 101 次。这是不是能解释你观察到的情况?还是说你是指每次内层循环的执行本身随着时间变得更慢了?