代码之家  ›  专栏  ›  技术社区  ›  cap

为什么原地赋值比在NumPy中创建新数组慢?

  •  0
  • cap  · 技术社区  · 10 月前

    我试图优化一段代码,该代码在循环中重复调用的函数内有分配。我使用jupyter运行了一些性能测试,结果对我来说是违反直觉的。

    给定数组 A , B ,我将在循环中执行这两个的矩阵乘法。

    • 方法1将没有预分配,结果将存储在 C ,
    • 方法2将有一个预分配的数组 D ,其中存储了乘法结果
    import numpy as np
    
    A = np.random.rand(10, 10)
    B = np.random.rand(10, 10000)
    D = np.random.rand(10, 10000)
    
    # Approach 1, no pre-allocation
    for i in range(20000):
        C = A @ B
    
    # Approach 2, pre-allocated D
    for i in range(20000):
        D[:] = A @ B
    

    我预计第二种方法会更快,因为它重用了D中的内存,而不是每次分配一个新的数组。然而,对循环进行计时表明,第一种方法实际上快了2倍。

    为什么原地赋值(D[:]=A@B)比创建新数组(C=A@B)慢?这与numpy的内存管理有关吗?

    1 回复  |  直到 10 月前
        1
  •  3
  •   user2357112    10 月前

    你是 再利用 D 的记忆。这两种方法每次都会分配一个新数组。然后,您的第二种方法将此新数组的内容复制到 D ,需要额外的时间来做到这一点。

    如果你想直接将结果写入 D 的记忆,应该是

    np.matmul(A, B, out=D)