【问题标题】:numpy.sum may be slower than Python for-loopnumpy.sum 可能比 Python for-loop 慢
【发布时间】:2013-01-12 01:24:44
【问题描述】:

在特定轴上对数组求和时,专用数组方法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倍以上!这里发生了什么 (wr)on(g),我不能相信 numpy 中的矢量化方法比 for 循环更快吗?

【问题讨论】:

  • 你在比较苹果和橘子。第二个是在 1000 长 C 循环矢量化加法上的 3 项长 python 循环,第一个是(可能)1000 长 C,创建超过 3-4 项的循环。在第二种情况下,内存布局访问也更好,但差别不大。
  • 换句话说...是的,您可以相信它会更快...但不要认为python那么慢以至于您无法在不等待年龄的情况下对3个项目执行for循环.. .
  • @seberg 我不同意苹果和橘子的观点:这里的 for 循环比numpy.sum 高效得多,这必须解释一下。

标签: python performance numpy vectorization


【解决方案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

在这里您清楚地看到,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 代码,但我怀疑造成差异的是连续内存访问或跨步访问。

正如这个例子所示,在实现数值算法时,正确的内存布局非常重要。矢量化代码不一定能解决所有问题。

【讨论】:

  • 是的,内存布局很重要,尽管在他的情况下,他总结了几个项目......他看到的不同之处在于,由于调用最低级别的循环,reduce 方法在 C 内部有更多的开销10000 次而不是 4 次,老实说,我认为这本身并不值得担心。
  • 您可以在上面的代码中使用不同的N, Mnumpy.sum 中存在效率低下的区域,这是正常的,无需担心,除非这成为您应用程序的瓶颈。对我来说,在 C 代码中采用的一些恢复效率的策略可以应用于 python 解释器级别并且优于 numpy,这对我来说是违反直觉的! OP提出了一个非常好的观点。 (最后一点:当然,如果这种减少是瓶颈,那么定制的、微调的 C 扩展是最好的解决方案;还应该分析供应商库(如 MKL)的接口。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多