为什么numpy的效率在快速下降?

r9f1avp5  于 2023-04-30  发布在  其他
关注(0)|答案(1)|浏览(101)

我有一个关于numpy在增加矩阵/向量运算中的元素数量时的效率的问题。
如果你看下面的例子,对于10_000数组中的一些元素,每一步的时间长度大致相同。操作31、32和33花费约450 ms。此外,在最后一行36上,时间长度大约是每个单独操作的长度的两倍,这似乎是合理的。

In [1]: import numpy as np

In [29]: m = np.random.randn(10_000)

In [30]: shift = 1.0098765

In [31]: %timeit m - m.reshape(len(m), 1)
407 ms ± 5.75 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [32]: matrix = m - m.reshape(len(m), 1)

In [33]: %timeit matrix - shift
443 ms ± 6.45 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [34]: matrix_s = matrix - shift

In [35]: %timeit np.abs(matrix_s)
455 ms ± 3.77 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [36]: %timeit np.abs(matrix - shift)
936 ms ± 89.3 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

下面我将元素的数量增加到20_000
我再次看了一下时间长度,但我不明白结果,因为与10_000元素的情况相反,它们看起来不一致(对我来说)。操作39与下面的操作相比非常快(快10倍),而之前的长度相同。此外,操作44比我分解相同计算的操作41和43之和长两倍。

In [37]: m = np.random.randn(20_000)

In [39]: %timeit m - m.reshape(len(m), 1)
1.53 s ± 47 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [40]: matrix = m - m.reshape(len(m), 1)

In [41]: %timeit matrix - shift
18.5 s ± 5.59 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [42]: matrix_s = matrix - shift

In [43]: %timeit np.abs(matrix_s)
27.3 s ± 6.65 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

In [44]: %timeit np.abs(matrix - shift)
1min 15s ± 4.29 s per loop (mean ± std. dev. of 7 runs, 1 loop each)

矩阵的大小是10^8个元素,它开始很大,但我认为不是那么大。如果我很好地计算它,对于10_000的大小,我有一个763 Mb的矩阵阵列,而对于20_000,它是3Gb。这是交换问题吗?

bvk5enib

bvk5enib1#

这可能是使用二维数组的副作用。
使用m - m.reshape(len(m), 1)创建二维数组时,它将包含len(m) ** 2元素。这意味着当m中有10000个元素时,它将有10_000 ** 2 = 100_000_000个元素。
len(m) == 20_000相比。在这种情况下,我们的2D数组将有400_000_000个元素(是我们的数组10000的4倍)。
从上面所做的基准测试来看,这似乎是正确的。reshape操作大约需要3.对于2D阵列,长度为75倍。
对于以后的操作,由于内存速度的原因,操作可能会开始变慢。特别是,如果您的系统在资源上受到限制,这将导致问题。
对于最后一个操作,Python很可能使用内存来存储matrixmatrix - shiftnp.abs(matrix - shift),我认为这所需的内存会导致性能问题。

相关问题