【发布时间】:2020-03-11 16:22:09
【问题描述】:
在测量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)
即np.zeros 对于大尺寸的速度最高可提高 40 倍。
不确定这些差异是否适用于所有架构/操作系统,但我至少在 x86-64 Windows 和 Linux 上观察到了这种差异。
np.zeros和np.full之间的哪些区别可以解释不同的内存消耗和不同的运行时间?
【问题讨论】:
-
添加
np.ones可能也很有趣。 -
np.zeros与操作系统一起进行“惰性”初始化:`stackoverflow.com/questions/27574881/… -
短版:答案与Why malloc+memset is slower than calloc?的答案相同。
calloc/numpy.zeros实际上并没有在分配时写入内存(对于足够大的分配),malloc+memset/numpy.full确实(理论上,它对于零值,可以特例full;实际上它似乎不是)。
标签: python performance numpy