假设我们有一个向量和一个矩阵:

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/

10-12 16:45