我试图提高一些Python代码的性能。在该代码中,矩阵的一列(numpy数组)必须临时更改
给出的代码如下所示:
def get_Ai_copy(A, b, i):
Ai = A.copy()
Ai[:,i] = b[:,0]
return Ai
现在,我认为不创建整个矩阵a的副本应该是一个很大的改进(在所使用的示例中,矩阵是500x500,所有条目都严格大于0),而只是使用np.column_stack()
从我需要的列中创建一个新的临时矩阵,如下所示:
def get_Ai(A, b, i):
return np.column_stack([A[:,:i], b, A[:,i+1:]])
我本以为这会大大提高性能,但事实证明,它实际上比给定的方法慢:
我以两种方式运行了100次,并比较了平均运行时间:
number_tests = 100
copy_times = np.empty(number_tests)
stacking_times = np.empty(number_tests)
for j in range(number_tests):
t0 = time.time()
for i in range(500):
Ai = get_Ai_copy(A, b, i)
t1 = time.time()
copy_times[j] = t1 - t0
# print(f'-- Run # {j}: CPU time for copying Ai = %g seconds'%(t1 - t0))
t0 = time.time()
for i in range(500):
Ai = get_Ai(A, b, i)
t1 = time.time()
stacking_times[j] = t1 - t0
# print(f'-- Run # {j}: CPU time for column stacking Ai = %g seconds'%(t1 - t0))
# print()
print(f'Copying times average: {np.mean(copy_times)}')
print(f'Stacking times average: {np.mean(stacking_times)}')
结果是:
平均复印次数:0.19957998037338257
平均堆叠时间:0.22774386405944824
我不明白为什么会这样。
有什么解释我没看到吗?复制整个阵列是否比获取3个切片更方便缓存?如果是,有人知道原因吗
旁白:
我在一台Jupyter笔记本电脑上运行它,一台配备Intel i7 10750H(12mb缓存)和32GB Ram的笔记本电脑。
A
始终是一个非奇异矩阵,如果这很重要的话
numpy数组的
copy
方法将触发代码,该代码将以最大CPU速度在所有数组数据上进行复制,使用本机代码-如果每个元素有500x500x8字节,我们所说的是约2MB的数据-即使在CPU的缓存中也非常适合。 numpy只需要为单个Python对象创建元数据另一方面,
column_stack
运行一些Python代码(虽然不是在细粒度对象上运行,否则会更糟),并最终复制数组(它获取当前数组的片-不复制片,但在内部调用np.concatenate,从而触发复制)。因此,您只需增加部分复制数据的开销,以及在过程中创建10个Python级别的数组对象(在切片、连接等之间)所需的一些杂耍——这就弥补了您所获得的10%的额外时间相关问题 更多 >
编程相关推荐