Python 为什么Numpy在创建零数组方面比用零替换现有数组的值快得多?
我有一个数组,用于跟踪各种值。阵列的大小为Python 为什么Numpy在创建零数组方面比用零替换现有数组的值快得多?,python,arrays,performance,numpy,Python,Arrays,Performance,Numpy,我有一个数组,用于跟踪各种值。阵列的大小为2500x1700,因此不是很大。在会话结束时,我需要将该数组中的所有值重置回零。我尝试创建一个新的零数组,并用零替换数组中的所有值,创建一个全新的数组要快得多 代码示例: for _ in sessions: # Reset our array tracking_array[:,:] = 0 1.44 s ± 19.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) 对 f
2500x1700
,因此不是很大。在会话结束时,我需要将该数组中的所有值重置回零。我尝试创建一个新的零数组,并用零替换数组中的所有值,创建一个全新的数组要快得多
代码示例:
for _ in sessions:
# Reset our array
tracking_array[:,:] = 0
1.44 s ± 19.1 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
对
for _ in sessions:
# Reset our array
tracking_array = np.zeros(shape=(2500, 1700))
7.26 ms ± 133 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)
为什么创建一个全新的数组要比仅仅替换数组中的值快得多?原因是在主流操作系统(Windows、Linux和MaxOS)上,数组没有填充到内存中。Numpy通过向操作系统(OS)请求虚拟内存中的零填充区域来分配零填充阵列。该区域不直接映射到物理RAM中。当您在虚拟内存中读/写页面时,映射和零初始化通常由操作系统惰性地执行。例如,稍后将数组设置为1时,将支付此费用。这是一个证明: [19]中的
:%timeit res=np.zeros(shape=(25001700))
每个回路10.8µs±118 ns(7次运行的平均值±标准偏差,每个100000个回路)
[20]中:%timeit res=np.one(shape=(25001700))
每个回路7.54 ms±151µs(7次运行的平均值±标准偏差,每个100个回路)
前者意味着RAM吞吐量至少为4.2 GiB/s,这并不高,但公平。后者意味着RAM吞吐量至少约为2930 GiB/s,这是非常高的,因为我的机器(以及任何标准的台式机/服务器机器)几乎无法达到36 GiB/s(使用仔细优化的基准)。有一个C函数用于清空内存区域。当您使用可以使用它的代码路径时,它非常非常便宜。还有一个标准库C函数,用于分配一块内存并在此时将其归零。Wheras
tracking_array[:,:]=0
也需要能够处理非零值,因此它不能采用优化路径。这就解释了这一点。非常感谢。