Joh*_*ith 8 c# arrays performance jagged-arrays
我在我的程序中遇到性能瓶颈,我需要在紧密的循环中数百万次访问数组中的元素.
我环顾四周,普遍的共识似乎是即使多维数组应该更快,它们的底层实现也是低效的,所以只需使用锯齿状数组.我对它进行了分析,肯定的是,锯齿状阵列的速度提高了50%.精细.
但是,我也尝试过手动索引(例如,通过执行类似这样的操作object value = array[i * 24 + j]; (where 24 is an array size)来模拟多维数组的行为:并通过乘法来访问它,并使用乘法来模拟多维数组.
令人惊讶的是,对于访问而言,这也比锯齿状阵列快15%(我只关心).这让我感到很难过,因为一方面,手动重新创建多维数组比C#的内置实现要快得多,而且两个,与仅使用锯齿状/多维数组进行索引相比,获取指标所涉及的数学更为丑陋.
有什么办法可以在不使用我自己的手动索引的情况下收回速度优势吗?当然可以设置或检查某种优化来模拟这种行为?为什么数组的C#实现效率低下?
令人惊讶的是,对于访问,这也比锯齿状阵列快15%左右
这应该不足为奇,因为索引锯齿状数组需要额外的解引用.写作时a[i][j],计算机必须执行以下操作:
i锯齿状数组内嵌套数组的位置aa[i](第一个取消引用)j在a[i]j的a[i](第二解引用)在向量中折叠2D数组时,计算机只执行一次取消引用:
从本质上讲,您正在交换乘法的解引用; 乘法更便宜.
此外,您可以获得内存中元素的连续性 - 使用锯齿状数组无法保证这一点.对于对缓存命中敏感的代码,这一点很重要.
有什么办法可以在不使用我自己的手动索引的情况下收回速度优势吗?
使用索引方案是一种方法.您可以通过创建一个类来隐藏代码的查看者,比如,Matrix2D暴露一个带有operator []两个索引并产生值的类.这样,计算偏移量的代码将对程序的读者隐藏,因为该a[i * 24 + j]部件看起来像a[i, j]