在我的程序中,我遇到了一个性能瓶颈,在这个瓶颈中,我需要在一个紧密的循环中访问数组中的元素数百万次。
我环顾四周,大家的共识似乎是,即使多维数组应该更快,但它们的底层实现效率很低,所以只需使用交错数组即可。我对它进行了详细分析,而且确实,锯齿状阵列的速度快了50%。很好。
不过,我也尝试过手工索引(如模拟多维数组的行为,只需执行如下操作:object value = array[i * 24 + j]; (where 24 is an array size)
并通过带有乘法的一维数组访问它以模拟多维数组)。
令人惊讶的是,这也比锯齿状数组快约15%的访问(所有我关心的)。这让我很难过,因为一方面,手工创建多维数组的速度比C#的内置实现要快得多,而第二,与仅用锯齿状/多维数组进行索引相比,处理指标所涉及的数学更丑陋。
有什么我可以做的,以收回速度的好处,而不必使用我自己的手工索引?当然,可以设置或检查某种类型的优化来模拟这种行为?为什么数组的C#实现效率这么低?
发布于 2015-03-12 15:35:17
令人惊讶的是,对于访问,这也比锯齿数组快15%左右。
这一点都不奇怪,因为索引锯齿数组需要额外的取消引用。编写a[i][j]
时,计算机必须执行以下操作:
i
在锯齿数组a
中的位置a[i]
的位置(第一次取消引用)j
在a[i]
中的位置j
of a[i]
(第二次取消引用)的位置获取值在向量中折叠2D数组时,计算机只执行一次取消引用操作:
从本质上说,你是在用去引用来换取乘法;乘法比较便宜。
此外,您还可以获得内存中元素的连续性--这是您无法用锯齿数组保证的。对于对缓存命中敏感的代码来说,这一点变得非常重要。
有什么我可以做的,以收回速度的好处,而不必使用我自己的手工索引?
使用您的索引方案是一种方法。您可以通过创建一个类(比方说,Matrix2D
),公开一个接受两个索引并生成值的operator []
来对代码的查看者隐藏它。这样,计算偏移量的代码就会对程序的读者隐藏起来,因为a[i * 24 + j]
部件看起来像a[i, j]
。
https://stackoverflow.com/questions/29013788
复制相似问题