【发布时间】: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