【问题标题】:why is iterating over an Numpy array faster than direkt operations为什么迭代 Numpy 数组比直接操作更快
【发布时间】:2022-11-22 23:23:57
【问题描述】:

我想知道与按列执行操作相比,迭代数组的前两个维度是否明显更慢。令我惊讶的是,如果发现按元素进行操作实际上更快。有人可以解释吗?

这是代码:

def row_by_row(arr, cop):

    for i in range(arr.shape[0]):
        for ii in range(arr.shape[1]):
            arr[i, ii] = cop[i, ii].copy()

    return arr

def all(arr, cop):

    for i in range(arr.shape[1]):
        arr[:,i] = cop[:, i].copy()

    return arr

print(timeit.timeit("row_by_row(arr, cop)", setup= "arr = np.ones((26, 15, 5000)); cop = np.random.random((26, 15,5000))",number=50, globals=globals()))
print(timeit.timeit("all(arr, cop)",setup= "arr = np.ones((26, 15, 5000)); cop = np.random.random((26, 15,5000))",  number=50, globals=globals()))

这是时间:

0.12496590000000007
0.4989047

【问题讨论】:

  • 我有 python-3.10.6 和 numpy-1.21.5。我无法重现它。第二个对我来说更快。 0.104 对 0.097。快不了多少,但绝对不会慢。
  • 对我来说也非常接近结果
  • 诡异的。我有 python:3.9 和 numpy: 1.23.3。有时第二个更快,但大多数情况下它在帖子中。更奇怪的是,当我将第一个维度增加到 2000 时,第二个维度甚至更慢。
  • 差异太小,无法得出任何稳定的结论。您应该增加大小以获得更可靠的计时。
  • 我同意其他 cmet 的观点,即第二个更快 - 在我的情况下(python 3.7.7,numpy 1.18.5)第一个大约 200-300ms,第二个大约 130-200ms。另外我想注意到 .copy() 完全没用,如果您已经设置了一些列,它会自动将数据复制到那里。删除它可以将两次(但尤其是第二次)时间显着降低到第一次 150-250 毫秒和第二次 60-130 毫秒。

标签: python arrays algorithm numpy


【解决方案1】:

简短回答:

内存分配

长答案:

正如问题中的评论者指出的那样,测量结果似乎非常不可靠。将测量的操作次数增加到 2000 次会得到更稳定的结果

行:3.519135099995765

全部:5.321293300003163

肯定会影响性能的一件事是数组在内存中的存储方式以及我们有多少缓存命中/未命中。

def matrix(arr, cop):

    for i in range(arr.shape[0]):
        arr[i] = cop[i].copy()

    return arr

这在性能上比复制“列”好一点

矩阵:4.6333566999965115

它仍然比逐行通过它慢。为什么?

为此,让我们从循环中退一步

def just_copy(arr, cop):
    return cop.copy()

副本:5.482903500000248

只是复制整个东西,我们又变慢了!

我假设,循环遍历数组更快的原因主要是内存分配。复制 NumPy 结构也可能有一些额外的开销。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 1970-01-01
    • 2019-09-30
    • 2023-04-06
    • 1970-01-01
    • 2017-03-28
    相关资源
    最近更新 更多