【发布时间】:2015-01-21 11:05:22
【问题描述】:
考虑以下两个函数,它们基本上将一个小序列中的每个数字与一个大序列中的每个数字相乘以构建一个二维数组,然后将数组中的所有值加倍。 noloop() 使用 2D numpy 数组的直接乘法并返回结果,而 loop() 使用 for 循环遍历 arr1 并逐渐构建输出数组。
import numpy as np
arr1 = np.random.rand(100, 1)
arr2 = np.random.rand(1, 100000)
def noloop():
return (arr1*arr2)*2
def loop():
out = np.empty((arr1.size, arr2.size))
for i in range(arr1.size):
tmp = (arr1[i]*arr2)*2
out[i] = tmp.reshape(tmp.size)
return out
我预计 noloop 即使对于少量迭代也会更快,但对于上述数组大小,loop 实际上更快:
>>> %timeit noloop()
10 loops, best of 3: 64.7 ms per loop
>>> %timeit loop()
10 loops, best of 3: 41.6 ms per loop
有趣的是,如果我在这两个函数中删除 *2,noloop 会更快,但只是稍微:
>>> %timeit noloop()
10 loops, best of 3: 29.4 ms per loop
>>> %timeit loop()
10 loops, best of 3: 34.4 ms per loop
对这些结果是否有很好的解释,是否有明显更快的方法来执行相同的任务?
【问题讨论】:
-
我得到
noloop()比loop()快(约15%),无论如何... -
我在 python2 和 python3 上也得到了相反的结果。
-
我得到
loop更快,正如 OP 所建议的那样(在我的机器中提高了 28%)。 Python 3.4.1 | Anaconda 2.1.0,IPython 2.2.0 -
OP 值来自 Spyder,即 QT IPython 控制台。我使用 Spyder 之外的 QT IPython 控制台得到了相同的结果。奇怪的是,在普通的 IPython 控制台中,
noloop()似乎和以前一样长(60-70 毫秒),而loop()比noloop()长了几毫秒,即比 QT 控制台慢得多。 -
这里也一样,
noloop()在我的机器上快了约 10%。