假设我们有一个向量和一个矩阵:
X = np.random.random((1, 384)).astype('float32')
Y = np.random.random((500000, 384)).astype('float32')
为什么
np.dot(X, Y.T)
比 X - Y
快得多?In [8]: %timeit np.dot(X, Y.T)
10 loops, best of 3: 42.4 ms per loop
In [9]: %timeit X - Y
1 loop, best of 3: 501 ms per loop
我该怎么做才能使这样的减法像点积一样快?
最佳答案
输出的大小很重要,因为输出必须写入内存,而写入大数组需要时间。 dot(X, Y.T)
的形状是 (1, 500000)。 X-Y 的形状是 (500000, 384)。
在我的测试中,X-Y 花费的大部分时间是为输出分配一个数组。比较:
%timeit X - Y
1 loop, best of 3: 449 ms per loop
使用预先分配的空间
Z = np.zeros_like(Y)
,%timeit np.subtract(X, Y, out=Z)
10 loops, best of 3: 181 ms per loop
所以,如果你必须重复做这种减法,拥有一个合适形状和类型的预分配数组将节省一半以上的执行时间。
我不认为你的情况下的减法可以像乘法一样快。要进行的算术运算量大致相同:X 的每个条目都满足 Y 的 500000 个条目。当您进行乘法(求和步骤)时将结果合并这一事实只会有所帮助,因为 CPU 会快速处理它已经存在的数字,因此它只有一个数字要发回。所以:大约相同的工作量,但对于减法的情况,内存写入量是 384 倍。
这是一个证明,当两者(方阵)的输出大小相同时,减法 比 更快:
X = np.random.random((1000, 1000)).astype('float32')
Y = np.random.random((1000, 1000)).astype('float32')
%timeit np.dot(X, Y.T)
100 loops, best of 3: 28.7 ms per loop
%timeit X - Y
1000 loops, best of 3: 579 µs per loop
关于python - 为什么矩阵减法比numpy中的点积慢得多?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/47688824/