numpy.sum可以比Python比较慢的for循环(numpy.sum may be slowe

2019-07-18 21:11发布

当求和特定的轴的阵列,专用阵列方法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循环快?

Answer 1:

不,你不能。 当你的有趣的例子指出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代码,但我怀疑其实差别是连续内存访问或访问跨入。

由于这方面的例子表明,实现数值算法时,正确的内存布局具有十分重要的意义。 量化代码不一定可以解决所有问题。



文章来源: numpy.sum may be slower than Python for-loop