访问多维数组是否比线性数组慢?

时间:2012-11-06 19:43:36

标签: c++ arrays

我正在为我的3D几何库开发一个4x4矩阵C ++类。我对如何以更有效的方式表示矩阵数据值感到困惑。

那是因为The Matrix and Quaternions FAQ说:

  

使用二维数组也会导致CPU性能下降     C编译器通常会使用乘法运算     解析数组索引操作。   因此,坚持使用线性阵列会更有效。

  1. 对多维数组的访问是否真的比线性数组慢?
  2. 我是否真的更喜欢多维线性阵列来存储4x4矩阵数据值?

2 个答案:

答案 0 :(得分:3)

我所知道的大多数实现都使用带有包装的一维数组,通过MACROS或方法来访问2D数据。我自己不能说哪个更快,我几乎看不出这个真正重要的情况。

然而,据说我仍然建议使用1D阵列,原因如下:

  1. 更容易动态分配和释放(如果你想动态分配你的数据并维护矩阵[i] [j]模式,那么你正在分配一个数组数组 - 分配更多的bug更慢,你必须释放每个单独排列)
  2. 如果你动态分配并且必须将数据复制到3d方库,比如OpenGL或OpenCV,你就会遇到麻烦,因为他们需要数据是连续的。
  3. 从文件或其他持久存储中存储和读取矩阵会更容易。
  4. 即使你没有动态分配,你也必须做各种丑陋的演员来处理内存到3d派对库的转移。
  5. 使用方法创建一个结构非常容易,可以对数据进行有效的2d访问,而无需乘法或不明确的索引。或者就此而言,使用MACROS来封装丑陋的乘法。
  6. 你甚至可以创建一个看起来像下一个样本的结构,并保持1d数组的相同优点,并具有2d数组的可读性:
  7. 
    template<typename T>
    struct Matrix4x4
    {
        struct index
        {
            int row, col;
            index(int r = 0, int c = 0)
                : row(r), col(c){}
            index(index const & cp)
                : row(cp.row), col(cp.col)
            {
            }
            //Assignment ommited for brevity
        };
        /*
            Constructors, Assignments etc. ommited for brevity
        */
        T m00, m01, m02, m03;
        T m10, m11, m12, m13;
        T m20, m21, m22, m23;
        T m30, m31, m32, m33;
    
        T * toArray() const
        {
            return &m00;
        }
        T * toArray()
        {
            return &m00;
        }
    
        T * row(int r)
        {
            return (&m00) + r*4;
        }
        T * row(int r) const
        {
            return (&m00) + r*4;
        }
    
        T & operator()(int r, int c)
        {
            return *row(r)[c];
        }
        T const & operator()(int r, int c) const
        {
            return *row(r)[c];
        }
    
        T & operator[](index const & idx)
        {
            return row(idx.row)[idx.col];
        }
        T const & operator[](index const & idx) const
        {
            return row(idx.row)[idx.col];
        }
    
    };
    
    

    在您的代码中,您可以:

    typedef Matrix4x4<double> Matrix4x4d;
    
    Matrix4x4d mat;
    /* You can do any of the following */
    mat.m23 = 6.0;
    mat(2,3) = 6.0;
    mat[Matrix4x4d::index(2,3)] = 6.0;
    mat.row(2)[3] = 6.0;
    mat.toArray()[2*4 + 3] = 6.0;
    
    #define M(m,r,c) (*((&m.m00) + r*4 + c))
    
    M(mat,2,3) = 6.0;
    

    多年来,我自己实施了几个矩阵库,并且总是选择1d解决方案。

答案 1 :(得分:0)

您可以在第一维中存储指向一维数组的指针,然后在第二维中存储行长度的一维数组。

从我的记忆中,间接比乘法更便宜。

访问/编辑成员的语法是相同的。唯一的区别是你分配/解除分配数组时。