numpy.sum可能比Python for循环慢 [英] numpy.sum may be slower than Python for-loop

查看:396
本文介绍了numpy.sum可能比Python for循环慢的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在特定轴上对数组求和时,专用数组方法array.sum(ax)实际上可能比for循环要慢:

When summing an array over a specific axis, the dedicated array method array.sum(ax) may actually be slower than a for-loop :

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倍以上!这里的(wr)是怎么回事,难道我不相信numpy中的矢量化方法比for循环更快吗?

The vectorized method is more than 4 times slower than an ordinary for-loop! What is going (wr)on(g) here, can't I trust vectorized methods in numpy to be faster than for-loops?

推荐答案

不,您不能.正如您的有趣示例所指出的那样,numpy.sum可能不是最优的,并且通过显式的for循环更好地布局操作会更有效率.

No you can't. As your interesting example points out numpy.sum can be suboptimal, and a better layout of the operations via explicit for loops can be more efficient.

让我展示另一个示例:

>>> 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

在这里您可以清楚地看到,numpy.sum如果在快速运行索引上求和(v是C连续的),则是最优的;而在慢速运行轴上求和则是次优的.有趣的是,对于for循环,相反的模式是正确的:

Here you clearily see that numpy.sum is optimal if summing on the fast running index (v is C-contiguous) and suboptimal when summing on the slow running axis. Interestingly enough an opposite pattern is true for for loops:

>>> 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代码,但是我怀疑造成差异的是连续的内存访问或跨步访问.

I had no time to inspect numpy code, but I suspect that what makes the difference is contiguous memory access or strided access.

如本例所示,实现数字算法时,正确的内存布局非常重要.向量化的代码不一定能解决所有问题.

As this examples shows, when implementing a numerical algorithm, a correct memory layout is of great significance. Vectorized code not necessarily solves every problem.

这篇关于numpy.sum可能比Python for循环慢的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆