Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python numpy.sum性能取决于轴_Python_Performance_Numpy - Fatal编程技术网

Python numpy.sum性能取决于轴

Python numpy.sum性能取决于轴,python,performance,numpy,Python,Performance,Numpy,在numpy数组中对维度求和时,第一个轴和最后一个轴之间是否存在性能差异 具体来说,考虑以下代码,sum1和sum2中的哪一个执行得更快 import numpy as np a = np.ones((1000,200)) b = np.ones((200,1000)) sum1 = np.sum(a, axis=0) sum2 = np.sum(b, axis=-1) 我相信这个问题实际上归结为numpy如何在内部存储维度,并且可以覆盖它以使用行或列格式。但是,当使用默认设置时,以下哪项会更

在numpy数组中对维度求和时,第一个轴和最后一个轴之间是否存在性能差异

具体来说,考虑以下代码,
sum1
sum2
中的哪一个执行得更快

import numpy as np
a = np.ones((1000,200))
b = np.ones((200,1000))
sum1 = np.sum(a, axis=0)
sum2 = np.sum(b, axis=-1)

我相信这个问题实际上归结为numpy如何在内部存储维度,并且可以覆盖它以使用行或列格式。但是,当使用默认设置时,以下哪项会更快?另外,关于N维数组呢?

很容易检查是否存在性能差异(IPython,我增加了一点数字以产生更明显的差异):


现在,当您在
np.sum
中遇到实际性能问题时,您可能已经耗尽了内存,但确实存在差异。默认情况下,NumPy数组存储在中,因此首先是第一行,然后是第二行,以此类推。因此,在外部维度中求和(或操作)会更快,因为缓存会更有效。简单地说,在第一种情况下,当您获得数组的第一个元素时,一组连续的数据将与之一起到达缓存,因此当您要对下一个元素求和时,它们将已经存在。另一方面,在第二种情况下,要求和的元素彼此距离很远(实际上是2000个元素的距离),因此缓存在列方面不会有多大帮助。这并不是说缓存没有任何帮助,因为您要对所有列求和,所以缓存的数据仍然会在一定程度上被重用,但效率不高。这是一个相当粗略的近似值,通常有几个缓存级别,一些在内核之间共享,一些不共享,了解一个或另一个代码对它的确切影响是一个复杂的主题,但总体思路是正确的。

您确定您的运行时间吗?我得到了相反的结果,这似乎更符合逻辑,因为对于b,输出的每个值都是相邻内存单元的总和,因此缓存效率非常高。@Labo我刚刚在另一台计算机上再次运行了相同的代码片段(NumPy 1.14.0与MKL、Python 3.6.4 Anaconda、Win10、Core i7-6700HQ)我得到了与我发布的结果相似的结果,但是,尽管我不记得我发布这篇文章的那一刻,我认为我的推理可能确实是颠倒的。然而,我想知道NumPy到底是如何实现这个总和的。如果,对于第一种情况(
a
),我取第一整行,然后添加第二行,然后是第三行,以此类推,这实际上是缓存效率。如果我计算第一个最终元素,然后是第二个元素,等等,那么它就不是了。当对一行或一列求和->3µs vs 30µs时,可以清楚地看到这一点。请看最后一段。
import numpy as np

a = np.ones((10000, 2000))
b = np.ones((2000, 10000))
%timeit np.sum(a, axis=0)
# 27.6 ms ± 541 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit  np.sum(b, axis=-1)
# 34.6 ms ± 876 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)