gpt4 book ai didi

python - np.zeros 和 np.full 内存消耗和性能差异的原因

转载 作者:行者123 更新时间:2023-12-03 13:37:38 29 4
gpt4 key购买 nike

在测量 np.zeros 的内存消耗时:

import psutil
import numpy as np

process = psutil.Process()
N=10**8
start_rss = process.memory_info().rss
a = np.zeros(N, dtype=np.float64)
print("memory for a", process.memory_info().rss - start_rss)

结果出乎意料 8192字节,即几乎为 0,而 1e8 双倍将需要 8e8 字节。

更换时 np.zeros(N, dtype=np.float64)来自 np.full(N, 0.0, dtype=np.float64) a 所需的内存是 800002048字节。

运行时间也有类似的差异:
import numpy as np
N=10**8
%timeit np.zeros(N, dtype=np.float64)
# 11.8 ms ± 389 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
%timeit np.full(N, 0.0, dtype=np.float64)
# 419 ms ± 7.69 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

IE。 np.zeros对于大尺寸,速度最多可提高 40 倍。

不确定这些差异是否适用于所有架构/操作系统,但我至少在 x86-64 Windows 和 Linux 上观察到了这一点。
np.zeros之间有哪些区别和 np.full可以解释不同的内存消耗和不同的运行时间吗?

最佳答案

我不信任 psutil对于这些内存基准,rss(常驻集大小)可能不是正确的度量标准。

使用标准库 tracemalloc 你可以获得正确的内存分配数字 - 对于这个 N 和 float64 dtype,它应该是大约 800000000 字节的增量:

>>> import numpy as np
>>> import tracemalloc
>>> N = 10**8
>>> tracemalloc.start()
>>> tracemalloc.get_traced_memory() # current, peak
(159008, 1874350)
>>> a = np.zeros(N, dtype=np.float64)
>>> tracemalloc.get_traced_memory()
(800336637, 802014880)

对于 np.full 之间的时序差异和 np.zeros , 比较 malloc 的手册页和 calloc ,即 np.zeros可以去 an allocation routine which gets zeroed pages .见 PyArray_Zeros --> 来电 PyArray_NewFromDescr_int 路过 1zeroed参数,然后有 a special case更快地分配零:
if (zeroed || PyDataType_FLAGCHK(descr, NPY_NEEDS_INIT)) {
data = npy_alloc_cache_zero(nbytes);
}
else {
data = npy_alloc_cache(nbytes);
}

它看起来像 np.full没有这个快速路径。那里的性能类似于首先执行 init 然后执行复制 O(n):
a = np.empty(N, dtype=np.float64)
a[:] = np.float64(0.0)
numpy开发人员可能已经添加了一条通往 np.full 的快速路径如果填充值为零,但为什么要添加另一种方法来做同样的事情 - 用户可以使用 np.zeros首先。

关于python - np.zeros 和 np.full 内存消耗和性能差异的原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60640460/

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