我有一些东西我需要一个2D数组,但为了更好的缓存性能,我宁愿让它实际上是一个普通的数组。这是我的想法,但我不知道这是一个可怕的想法:
const int XWIDTH = 10, YWIDTH = 10;
int main(){
int * tempInts = new int[XWIDTH * YWIDTH];
int ** ints = new int*[XWIDTH];
for(int i=0; i<XWIDTH; i++){
ints[i] = &tempInts[i*YWIDTH];
}
// do things with ints
delete[] ints[0];
delete[] ints;
return 0;
}
所以我的想法是,不是new
一堆数组(并将它们放在内存中的不同位置),而是指向我一次制作的数组。
delete[] (int*) ints;
的原因是因为我实际上是在一个类中执行此操作,它会保存[微不足道的]内存而不保存原始指针。
只是想知道是否有任何理由这是一个可怕的想法。或者,如果有一个更容易/更好的方式。目标是能够以ints[x][y]
而不是ints[x*YWIDTH+y]
访问数组。
编辑:一个简单的基准测试表明,如果没有优化器,我的方式会更快,但由于某种原因,gcc可能会以简单的方式更好地优化。
如果用gcc -O0编译,最好应该是堆栈,然后是我的,然后是正常的。如果你在X_MAX设置为较大值并且Y_MAX设置为较小值的情况下进行编译,并使用gcc -O3,则我的和堆栈应该非常快,但正常情况不会。如果你使X_MAX变小并且Y_MAX很大,那么正常的方法应该会胜出(因为某些原因,甚至超过了堆栈方法)。
答案 0 :(得分:2)
这种方法的问题在于它容易出错。我会告诉你在一个类中包装和访问你的2D数组中的各个元素。
class Array2D
{
private:
/* Pointer necessary for the choosen implementation */
public:
Array2D(unsigned int dim1, unsigned int dim2);
~Array2D() /* Needed, since you will be allocation memory for this class */
double operator()(unsigned int x, unsigned int y);
}
在这种情况下,如果您觉得需要更改分配,则只能更改方法实现,保持接口完好无损。其余的代码实际上只使用operator()和构造函数。它还可以帮助您防止内存泄漏。
答案 1 :(得分:1)
我认为你在过早的阶段不必要地进行微观优化。而不是担心这一点,只需尽可能最简单的方式使程序正常工作。
如果您需要2D数组,只需声明并使用它即可。错误和维护的减少将远远超过任何可能根本不存在的性能提升。
答案 2 :(得分:0)
我找到了更好的方法。 Boost有一个多维数组库:boost::multi_array
。
从this question获得了这个想法。