我对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]
还是我有什么特别的事要做
4条答案
按热度按时间h7wcgrx31#
你的问题是没有意义的。当你在代码和机器之间有一个完整的解释器、装箱的数字类型、所述类型的堆分配等时,缓存效率是你最不需要担心的。由于Python的内置序列类型在幕后使用(动态和过度分配的)C数组,同样的规则应该适用,但有两个主要的警告:
int
对象的list
时,CPU缓存只能帮助更快地获取这些指针,而不能处理这些指针后面的对象。如果你能衡量所有的差异,我会很惊讶。如果你想优化,有很多事情比这有效一千倍,也更明显。使用内置的NumPy,写一点C,使用Cython,或者简单地优化你的Python代码。
bqujaahr2#
如果你谈论的是Python * 数组 *,那么我会假设它们在内存中是线性布局的,所以是的,顺序访问将是访问它们的最友好的缓存方式。
如果你谈论的是Python * 列表 *,我会认为Python列表和列表中的对象不可能在内存中以线性的方式排列,因为列表中的每一项都可以是任意类型的,所以它最多看起来像一个指针的线性数组--所以实际访问每一项可能会在内存中跳跃。
此外,Python的一般开销可能会使任何缓存效果都可以忽略不计。
您可能还需要优化循环:
4dbbbstv3#
内部循环使用
j
作为索引,因此当数组的相邻部分由j
的相邻值索引时,您将获得最佳缓存性能。这是通过乘以i
而不是j
来实现的。因为你的数组是一维的,所以这个问题完全与语言无关--缓存是由处理器处理的,而不是由语言处理的。如果你使用的是二维数组,你可能会得到不同的答案。
wgx48brx4#
我强烈建议您考虑在Python中使用numpy来操作多维数组。
NumPy是用纯C后端编写的,所以你不会遭受解释代码的巨大装箱-拆箱惩罚。然后,* 也许 *,你至少可以测量缓存性能,并使用行优先与列优先顺序,strides等。