繁体   English   中英

为什么矩阵减法比numpy中的点积慢得多?

[英]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)

请原谅我,我不知道如何改善这种表现。

使用np.subtract(X,Y)几乎将执行时间减半。 它比XY快,但速度低于点积。 可能有帮助 在此输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM