【问题标题】:Overloaded operator for accessing member array elements in cpp: performance用于访问 cpp 中的成员数组元素的重载运算符:性能
【发布时间】:2017-01-21 15:49:16
【问题描述】:

我编写了一个简单的 Matrix 类,以便更轻松地访问单个数据数组元素。它将信息保存在标准数组中,并且各个元素通过重载的括号运算符 () 返回,但是,类对象上的重载 () 运算符似乎比对数据数组的标准 [] 调用慢得多。帖子底部的课程代码。

我认为重载的运算符 (i, j) 将与在数据数组上调用 [i * ncols + j] 相同,但是,在运行一些测试之后,它大约慢了三倍。我已经在两个简单的函数上测试了这个理论:

void square_array(double * data_array, int nrows, int ncols)
{
    for (int i = 0; i < nrows; i++)
    for (int j = 0; j < ncols; j++)
    {
        data_array[i * ncols + j] = data_array[i * ncols + j] * data_array[i * ncols + j];
    }
}

void square_mymatrix(MyMatrix & data_mymatrix, int nrows, int ncols)
{
    for (int i = 0; i < nrows; i++)
    for (int j = 0; j < ncols; j++)
    {
        data_mymatrix(i, j) = data_mymatrix(i, j) * data_mymatrix(i, j);
    }
}

通过 1000x1000 数组调用它们

// Define and fill data_array
square_array(data_array, rowsN, colsN);

// Define and fill data_mymatrix
square_mymatrix(data_mymatrix, rowsN, colsN);

第二个函数调用的时间是第一个函数的三倍(~4.1ms vs ~11.9ms)。为什么通过方括号运算符访问数据比使用 [] 慢得多?我在代码中的某个地方犯了错误吗?

下面是 MyMatrix 类的代码。

class MyMatrix
{
    double * data;
    int nrows;
    int ncols;

    public:
        // Standard constructur prividing a pre-existant array
        MyMatrix(double * data_array, int rows, int cols)
        {
            this->nrows = rows;
            this->ncols = cols;
            this->data = data_array;
        }
        //Empty constructor
        MyMatrix() {}

        //Simple functions to obtain rows and cols of the matrix
        int get_nrows() {return this->nrows;}
        int get_ncols() {return this->ncols;}

        // Overloaded bracket operator to access the values
        double & operator()(int i, int j) {return data[i * ncols + j];}

        // Overloaded bracket operator for constant objects:
        const double & operator()(int i, int j) const {return data[i * ncols + j];}
};

【问题讨论】:

  • 在询问性能时,指定编译器、版本和传递给它的选项总是有帮助的。
  • 我正在使用 gcc v 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 和:-std=c++11 -Wall -Wextra
  • -O3有什么变化吗?
  • 我刚刚使用了默认优化 (-O0),但是,在应用 -O2 或 O3 之后,两种方法之间的性能差异变得可以忽略不计。感谢您的 cmets,我从未意识到优化级别会对两种不同的实现产生如此不同的影响。
  • 不客气。那我补充一下答案。

标签: c++ arrays matrix operator-overloading


【解决方案1】:

使用-O2-O3 调用具有更高优化级别的GCC。这应该正确地将函数调用内联到operator() 并生成与直接访问数据的二进制代码相同的二进制代码。

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-20
    相关资源
    最近更新 更多