下面的代码重现了我在当前实现的算法中遇到的问题:
import numpy.random as rand
import time
x = rand.normal(size=(300,50000))
y = rand.normal(size=(300,50000))
for i in range(1000):
t0 = time.time()
y *= x
print "%.4f" % (time.time()-t0)
y /= y.max() #to prevent overflows
问题是,经过一定次数的迭代后,事情开始逐渐变慢,直到一次迭代花费的时间是最初的数倍。
减速图
Python 进程的 CPU 使用率始终稳定在 17-18% 左右。
我正在使用:
- Python 2.7.4 32位版本;
- 带有 MKL 的 Numpy 1.7.1;
- Windows 8。
最佳答案
正如@Alok 所指出的,这似乎是由 denormal numbers 引起的影响性能。我在我的 OSX 系统上运行它并确认了这个问题。我不知道在 numpy 中将非正规数刷新为零的方法。我会尝试通过避免非常小的数字来解决算法中的这个问题:你真的需要除以 y
直到它下降到 1.e-324
水平?
如果您避免使用低数字,例如通过在循环中添加以下行:
y += 1e-100
那么每次迭代你都会有一个恒定的时间(尽管由于额外的操作而变慢)。另一种解决方法是使用更高精度的算法,例如
x = rand.normal(size=(300,50000)).astype('longdouble')
y = rand.normal(size=(300,50000)).astype('longdouble')
这会使您的每一步成本更高,但每一步花费的时间大致相同。
在我的系统中看到如下对比:
关于python - 为什么迭代元素数组乘法在 numpy 中变慢?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16553660/