非常不寻常的时刻为Numpy数组分配和复制
非常不寻常的时刻为Numpy数组分配和复制
我最近观察到了Numpy数组的分配和复制问题:\n数组的分配时间是恒定的(相对于数组的大小);将另一个数组的内容复制到已分配的数组中所需的时间也会随数组大小的增加而增加。然而,问题是执行这两个操作所用的时间,并不仅仅是这两个操作各自所需时间的总和(参见下图):\nt(分配 + 复制) > t(分配) + t(复制)
。\n我无法理解额外花费的时间(随大小迅速增加)的原因。\n这是我用于计时的代码。计时是在Debian Stretch操作系统下,使用Intel Core i3 CPU(2.13 GHz)进行的。\n
import numpy as np import gc from timeit import default_timer as timer import matplotlib.pyplot as plt def time_all(dim1): N_TIMES = 10 shape = (dim1, dim1) data_1 = np.empty(shape, np.int16) data_2 = np.random.randint(0, 2**14, shape, np.int16) # 分配数组 t1 = timer() for _ in range(N_TIMES): data_1 = np.empty(shape, np.int16) alloc_time = (timer() - t1) / N_TIMES # 复制数组 t1 = timer() for _ in range(N_TIMES): data_1[:] = data_2 copy_time = (timer() - t1) / N_TIMES # 分配和复制数组 t1 = timer() for _ in range(N_TIMES): data_3 = np.empty(shape, np.int16) np.copyto(data_3, data_2) alloc_copy_time = (timer() - t1) / N_TIMES return alloc_time, copy_time, alloc_copy_time #END def # 测量经过的时间 gc.disable() # 禁用自动垃圾回收 times_elapsed = np.array([(size, ) + time_all(size) for size in np.logspace(2, 14, 1<<8, endpoint=True, base=2, dtype=int)]) gc.enable() # 绘制结果 plt.plot(times_elapsed[:,0], times_elapsed[:,1], marker='+', lw=0.5, label="alloc") plt.plot(times_elapsed[:,0], times_elapsed[:,2], marker='+', lw=0.5, label="copy") plt.plot(times_elapsed[:,0], times_elapsed[:,3], marker='+', lw=0.5, label="alloc©") plt.xlabel("数组维度") plt.legend() plt.savefig("alloc_copy_time.svg")