Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/346.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数组缓存与C数组缓存_Python_Caching - Fatal编程技术网

Python数组缓存与C数组缓存

Python数组缓存与C数组缓存,python,caching,Python,Caching,我对Python非常缺乏经验,并且我意识到这是非常基本的,但是Python缓存块与C相比有多好?例如,在C中: gridWidth = 100000 gridHeight = 100000 for (i=0; i<gridHeight; i++){ for (j=0; j<gridWidth; j++){ massiveNum += arr[i*gridWidth + j] } } 因为数据在第一个内存中被高效缓存 如果我在Python中追求同样

我对Python非常缺乏经验,并且我意识到这是非常基本的,但是Python缓存块与C相比有多好?例如,在C中:

gridWidth = 100000
gridHeight = 100000

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

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

       massiveNum += arr[i*gridWidth + j]
    }
}
因为数据在第一个内存中被高效缓存

如果我在Python中追求同样的速度,我能做一些简单的事情吗

for i in range(0,gridHeight):

    for j in range(0,gridWidth):

       massiveNum += arr[i*gridWidth + j]

或者我必须做一些特殊的事情吗?

如果您谈论的是Python数组,那么我会假设它们在内存中是线性排列的,所以是的,顺序访问将是访问它们的最方便缓存的方式


如果您谈论的是Python列表,我认为Python列表及其对象在内存中不可能以线性方式排列。因为列表中的每一项都可以是任何类型的,所以它充其量看起来就像一个指针的线性数组——所以实际访问每一项可能会跳过整个内存

此外,Python的一般开销可能使任何缓存效果都可以忽略不计

您可能还希望优化循环:

n = gridHeight * gridWidth
i = 0
while i < n:
    massiveNum += arr[i]
    i += 1
n=gridHeight*gridWidth
i=0
而i
你的问题没有意义。当您的代码和机器之间有一个完整的解释器、装箱的数字类型、所述类型的堆分配等时,缓存效率是您最不担心的。由于Python的内置序列类型在后台使用(动态和过度分配)C数组,因此应该应用相同的规则,但有两个主要注意事项:

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

如果你能像所有人一样衡量任何差异,我会感到惊讶。如果你想优化,有很多事情比这更有效,更明显。使用内置的,NoMPI,写一点C,使用Cython,或者简单地优化你的Python代码。

< P>我强烈建议你考虑在Python中使用多维数组。
NumPy是用纯C后端编写的,所以您不会受到解释代码的巨大装箱拆箱惩罚。然后,也许您至少能够测量缓存性能,并使用诸如行主顺序与列主顺序等内容。

内部循环使用
j
作为索引,因此当数组的相邻部分被
j
的相邻值索引时,您的最佳缓存性能将出现。这是通过乘以
i
而不是
j
来实现的


因为数组是一维的,所以这个问题完全与语言无关——缓存是由处理器处理的,而不是由语言处理的。如果您使用的是二维数组,您可能会得到不同的答案。

我完全误解了这个问题,不是吗?@agf:或者我完全误解了;)虽然从CPU缓存问题来看,
arr[i+j*gridWidth]
arr[i*gridWidth+j]
之间的区别似乎很熟悉。不,你的解释更有意义。
n = gridHeight * gridWidth
i = 0
while i < n:
    massiveNum += arr[i]
    i += 1