当求和特定的轴的阵列,专用阵列方法array.sum(ax)
实际上可以是慢于一个for循环:
v = np.random.rand(3,1e4)
timeit v.sum(0) # vectorized method
1000 loops, best of 3: 183 us per loop
timeit for row in v[1:]: v[0] += row # python loop
10000 loops, best of 3: 39.3 us per loop
该矢量方法比普通的for循环慢4倍以上! 这到底是怎么回事(G)(WR),我不能信任numpy的量化方法比for循环快?
不,你不能。 当你的有趣的例子指出numpy.sum
可能是次优和操作通过明确一个更好的布局for循环可以更有效率。
让我来告诉另一个例子:
>>> N, M = 10**4, 10**4
>>> v = np.random.randn(N,M)
>>> r = np.empty(M)
>>> timeit.timeit('v.sum(axis=0, out=r)', 'from __main__ import v,r', number=1)
1.2837879657745361
>>> r = np.empty(N)
>>> timeit.timeit('v.sum(axis=1, out=r)', 'from __main__ import v,r', number=1)
0.09213519096374512
在这里,您clearily看到numpy.sum
是最优的,如果总结上快速奔跑指数( v
是C-连续)上运行慢轴时,总结和次优。 有趣的是相反的图案是用于真正for
循环:
>>> r = np.zeros(M)
>>> timeit.timeit('for row in v[:]: r += row', 'from __main__ import v,r', number=1)
0.11945700645446777
>>> r = np.zeros(N)
>>> timeit.timeit('for row in v.T[:]: r += row', 'from __main__ import v,r', number=1)
1.2647287845611572
我没有时间去检查numpy
代码,但我怀疑其实差别是连续内存访问或访问跨入。
由于这方面的例子表明,实现数值算法时,正确的内存布局具有十分重要的意义。 量化代码不一定可以解决所有问题。