繁体   English   中英

为什么遍历 Numpy 数组比直接操作更快

[英]why is iterating over a Numpy array faster than direct operations

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

这是代码:

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

简短回答:

Memory 分配

长答案:

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

行:3.519135099995765

全部:5.321293300003163

肯定会影响性能的一件事是 arrays 如何存储在 memory 中以及我们有多少缓存命中/未命中。

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

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

我假设,通过 arrays 循环更快的原因主要是 memory 分配。 复制 NumPy 结构可能还会有一些额外的开销。

因为通过迭代列而不是行, all缓存效率都非常低。

numpy arrays 中的数据按维度存储 - 行,然后是列,第 3 维等。如果我们读取一行,它将是 memory 的连续段,可以有效缓存。 如果我们按列读取,这里是几个字节,跳过几个 KB,而不是读取更多字节,等等——这会导致很多缓存未命中。 如果我们增加第 3 维,例如增加到 50K,问题会变得更加明显。

按行读取,而不是按列读取,消除了差异:

def all_by_rows(arr, cop):
    for row in range(arr.shape[0]):
        arr[row, :] = cop[row, :].copy()
    return arr

具有timeit三维的时间:

1.249532633984927  # row_by_row - which is actually by third dimension
2.0826793879969046  # all
1.3391598959860858  # all_by_rows

没有不必要.copy() ,正如 Marco 所指出的:

1.0241080590058118
0.9834478280099574
0.6739323509973474

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM