为什么 for 循环比 numpy 的二维数组乘法更快
Why are for loops quicker than numpy for 2D array multiplication
考虑以下两个函数,它们基本上将小序列中的每个数字与较大序列中的每个数字相乘以构建二维数组,然后将数组中的所有值加倍。 noloop()
使用二维 numpy 数组和 returns 结果的直接乘法,而 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
这些结果是否有很好的解释,是否有更快的方法来执行相同的任务?
我无法重现您的结果,但我确实发现使用 numpy.multiply
可以显着提高速度(2 倍)。通过使用 out
参数,您可以利用内存已经分配的事实,并消除将 tmp
复制到 out
.
def out_loop():
out = np.empty((arr1.size, arr2.size))
for i in range(arr1.size):
np.multiply(arr1[i], arr2, out=out[i].reshape((1, arr2.size)))
out[i] *= 2
return out
我机器上的结果:
In [32]: %timeit out_loop()
100 loops, best of 3: 17.7 ms per loop
In [33]: %timeit loop()
10 loops, best of 3: 28.3 ms per loop
考虑以下两个函数,它们基本上将小序列中的每个数字与较大序列中的每个数字相乘以构建二维数组,然后将数组中的所有值加倍。 noloop()
使用二维 numpy 数组和 returns 结果的直接乘法,而 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
这些结果是否有很好的解释,是否有更快的方法来执行相同的任务?
我无法重现您的结果,但我确实发现使用 numpy.multiply
可以显着提高速度(2 倍)。通过使用 out
参数,您可以利用内存已经分配的事实,并消除将 tmp
复制到 out
.
def out_loop():
out = np.empty((arr1.size, arr2.size))
for i in range(arr1.size):
np.multiply(arr1[i], arr2, out=out[i].reshape((1, arr2.size)))
out[i] *= 2
return out
我机器上的结果:
In [32]: %timeit out_loop()
100 loops, best of 3: 17.7 ms per loop
In [33]: %timeit loop()
10 loops, best of 3: 28.3 ms per loop