代码之家  ›  专栏  ›  技术社区  ›  Brendan Long

这个二维数组初始化是个坏主意吗?

  •  1
  • Brendan Long  · 技术社区  · 15 年前

    我有一些东西我需要一个二维数组,但为了更好的缓存性能,我宁愿它实际上是一个普通的数组。这是我的想法,但我不知道这是否是一个可怕的想法:

    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可能会在简单的方法上更好地优化。

    http://pastebin.com/YDRuLuXv

    如果您使用gcc-o0编译,最好的应该是stack,然后是mine,然后是normal。如果编译时x_max设置为大值,y_max设置为小值,并使用gcc-o3,那么mine和stack应该非常快,但正常情况下不会。如果你把x-max变小,y-max变大,正常的方法应该赢(因为某种原因甚至超过了stack方法)。

    3 回复  |  直到 14 年前
        1
  •  2
  •   cake    15 年前

    这种方法的问题在于它容易出错。我会告诉你把分配和对单个元素的访问包装在一个类中。

    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);
    }
    

    在这种情况下,如果您觉得需要更改分配,那么只能更改方法实现,保持接口的完整性。剩下的代码实际上只使用操作符()和构造函数。它还可以帮助您防止内存泄漏。

        2
  •  1
  •   Larry Watanabe    15 年前

    我认为你的微观优化在太早的阶段是不必要的。不用担心这个问题,只要让程序以最简单的方式正常工作就行了。

    如果您需要一个二维数组,只需声明它并使用它。减少bug和维护比任何性能提升都更有价值,而这可能根本不存在。

        3
  •  0
  •   Brendan Long    14 年前

    我找到了更好的方法。Boost有一个多维数组库: boost::multi_array .

    这个主意是从 this question .