不行。正如你提供的有趣示例所指出的那样,
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
代码,但我怀疑差别在于连续内存访问或跨步访问。
正如这个例子所示,在实现数值算法时,正确的内存布局非常重要。向量化代码并不一定解决每个问题。
numpy.sum
更高效,这一点必须解释清楚。 - Stefano M