gpt4 book ai didi

python - numpy 中的最佳(广播)矩阵划分。是否避免使用临时数组?

转载 作者:太空狗 更新时间:2023-10-29 23:55:46 28 4
gpt4 key购买 nike

Numpy 允许对不同大小的矩阵进行加法/乘法/除法,前提是一定broadcasting rules被跟随。此外,创建 temporary arrays是 numpy 的主要速度障碍。

下面的 timit 结果让我很吃惊……这是怎么回事?

In [41]: def f_no_dot(mat,arr):
....: return mat/arr

In [42]: def f_dot(mat,arr):
....: denominator = scipy.dot(arr, scipy.ones((1,2)))
....: return mat/denominator

In [43]: mat = scipy.rand(360000,2)

In [44]: arr = scipy.rand(360000,1)

In [45]: timeit temp = f_no_dot(mat,arr)
10 loops, best of 3: 44.7 ms per loop

In [46]: timeit temp = f_dot(mat,arr)
100 loops, best of 3: 10.1 ms per loop

我认为 f_dot 会比较慢,因为它必须创建临时数组分母,并且我假设 f_no_dot 跳过了这一步。我应该注意到,对于 f_no_dot,这些时间是线性缩放的(数组大小,最大长度为 10 亿),并且比 f_dot 的线性缩放略差。

最佳答案

I thought that f_dot would be slower since it had to create the temporary array denominator, and I assumed that this step was skipped by f_no_dot.

就其值(value)而言,创建临时数组跳过,这就是为什么f_no_dot 较慢(但使用较少内存)的原因。

对相同大小的数组进行逐元素操作更快,因为 numpy 不必担心数组的步幅(维度、大小等)。

使用广播的操作通常会比不需要的操作慢一点。

如果您有空闲内存,创建临时副本可以加快速度,但会占用更多内存。

例如比较这三个函数:

import numpy as np
import timeit

def f_no_dot(x, y):
return x / y

def f_dot(x, y):
denom = np.dot(y, np.ones((1,2)))
return x / denom

def f_in_place(x, y):
x /= y
return x

num = 3600000
x = np.ones((num, 2))
y = np.ones((num, 1))


for func in ['f_dot', 'f_no_dot', 'f_in_place']:
t = timeit.timeit('%s(x,y)' % func, number=100,
setup='from __main__ import x,y,f_dot, f_no_dot, f_in_place')
print func, 'time...'
print t / 100.0

这会产生与您的结果相似的时间:

f_dot time...
0.184361531734
f_no_dot time...
0.619203259945
f_in_place time...
0.585789341927

但是,如果我们比较内存使用情况,事情就会变得更清楚一些......

xy 数组的总大小约为 27.5 + 55 MB,或 82 MB(对于 64 位整数)。 import numpy 等还有大约 11 MB 的开销。

x/y 作为新数组返回(即不执行 x/= y)将需要另一个 55 MB 数组。

100 次 f_dot 运行:我们在这里创建一个临时数组,因此我们预计会看到 11 + 82 + 55 + 55 MB 或 ~203 MB 的内存使用量。而且,这就是我们所看到的...... enter image description here

100 次 f_no_dot 运行:如果没有创建临时数组,我们预计峰值内存使用量为 11 + 82 + 55 MB,或 148 MB...
enter image description here...这正是我们所看到的。

因此,x/y 不是创建一个额外的 num x 2 临时数组来进行除法。

因此,与在两个相同大小的数组上运算相比,除法所花费的时间要长得多。

100 次 f_in_place 运行:如果我们可以就地修改 x,我们可以节省更多的内存,如果这是主要问题的话。 enter image description here

基本上,在某些情况下,numpy 会尝试以牺牲速度为代价来节省内存。

关于python - numpy 中的最佳(广播)矩阵划分。是否避免使用临时数组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7769525/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com