Python数组缓存与C数组缓存

azpvetkf  于 2023-02-28  发布在  Python
关注(0)|答案(4)|浏览(173)

我对Python非常缺乏经验,我意识到这是非常基础的,但是与C相比,Python缓存块的效果如何呢?例如,在C中:

gridWidth = 100000
gridHeight = 100000

for (i=0; i<gridHeight; i++){

    for (j=0; j<gridWidth; j++){

       massiveNum += arr[i*gridWidth + j]
    }
}

要比

massiveNum += arr[i + j*gridWidth]

因为数据在第一个中被有效地高速缓存。
如果我想在Python中达到同样的速度,我能做一些简单的事情吗

for i in range(0,gridHeight):

    for j in range(0,gridWidth):

       massiveNum += arr[i*gridWidth + j]

还是我有什么特别的事要做

h7wcgrx3

h7wcgrx31#

你的问题是没有意义的。当你在代码和机器之间有一个完整的解释器、装箱的数字类型、所述类型的堆分配等时,缓存效率是你最不需要担心的。由于Python的内置序列类型在幕后使用(动态和过度分配的)C数组,同样的规则应该适用,但有两个主要的警告:

  • 对于每一个Python操作(例如,类型检查、变量和成员查找、在调用方法之前创建“绑定方法”对象、数字强制),都有很多“隐藏”的内存访问,这可能会降低好处。
  • 在许多情况下(除非另有说明),所有容器都存储对装箱对象的引用,因此当您迭代int对象的list时,CPU缓存只能帮助更快地获取这些指针,而不能处理这些指针后面的对象。

如果你能衡量所有的差异,我会很惊讶。如果你想优化,有很多事情比这有效一千倍,也更明显。使用内置的NumPy,写一点C,使用Cython,或者简单地优化你的Python代码。

bqujaahr

bqujaahr2#

如果你谈论的是Python * 数组 *,那么我会假设它们在内存中是线性布局的,所以是的,顺序访问将是访问它们的最友好的缓存方式。
如果你谈论的是Python * 列表 *,我会认为Python列表和列表中的对象不可能在内存中以线性的方式排列,因为列表中的每一项都可以是任意类型的,所以它最多看起来像一个指针的线性数组--所以实际访问每一项可能会在内存中跳跃。
此外,Python的一般开销可能会使任何缓存效果都可以忽略不计。
您可能还需要优化循环:

n = gridHeight * gridWidth
i = 0
while i < n:
    massiveNum += arr[i]
    i += 1
4dbbbstv

4dbbbstv3#

内部循环使用j作为索引,因此当数组的相邻部分由j的相邻值索引时,您将获得最佳缓存性能。这是通过乘以i而不是j来实现的。
因为你的数组是一维的,所以这个问题完全与语言无关--缓存是由处理器处理的,而不是由语言处理的。如果你使用的是二维数组,你可能会得到不同的答案。

wgx48brx

wgx48brx4#

我强烈建议您考虑在Python中使用numpy来操作多维数组。
NumPy是用纯C后端编写的,所以你不会遭受解释代码的巨大装箱-拆箱惩罚。然后,* 也许 *,你至少可以测量缓存性能,并使用行优先与列优先顺序,strides等。

相关问题