[英]Why is matrix subtraction much slower than dot product in numpy?
假设我们有一个向量和一个矩阵:
X = np.random.random((1, 384)).astype('float32')
Y = np.random.random((500000, 384)).astype('float32')
为什么np.dot(X, YT)
比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, YT)
的形状是(1,500000)。 XY的形状是(500000,384)。
在我的测试中,XY占用的大部分时间是为输出分配一个数组。 相比:
%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的每个条目在任何一种情况下都满足50个条目的Y. 当你进行乘法(求和步骤)时结果组合的事实只有帮助,因为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
这只是一个评论,虽然您已经检查过。
我测试了广播是否是原因,但在这种情况下它与性能无关。
In [1]: import numpy as np
In [2]: X = np.random.random((1, 384)).astype('float32')
...: Y = np.random.random((500000, 384)).astype('float32')
In [3]: %timeit np.dot(X, Y.T)
...: %timeit X - Y
27.4 ms ± 910 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
324 ms ± 16.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
In [4]: import numpy.matlib
...: X = np.matlib.repmat(X, 500000, 1)
...: print(X.shape)
...: %timeit X - Y
(500000, 384)
351 ms ± 20.7 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
请原谅我,我不知道如何改善这种表现。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.