【发布时间】:2014-01-11 21:03:40
【问题描述】:
这个问题是这个问题的继续:2-dimensional array on heap, which version is faster?
我已经定义了类似的东西:
class Array
{
double *data;
int X;
int Y;
public:
Array(int X, int Y, double init = 0) : X(X), Y(Y)
{
data = new double [X*Y];
for (int i=0; i<X*Y; i++)
data[i] = init;
}
~Array() { delete[] data; }
double *operator[] (int x) { return (data+x*Y); }
};
我希望获得具有二维可读性的连续数组的速度优势。我以为class Array 会这样做,与
Array arr(1000,1000);
arr[x][y] = n;
与普通版本(几乎)一样快
double *arr = new double [1000*1000];
arr[x*1000+y] = n;
因为operator[] 被定义为inline。
但纯版本要快得多,而封装版本仅比真正的二维版本快一点double **arr; ...; arr[x][y] = n; 不是真的,请参阅 Edit2
这正常吗?我正在 VC++ 2010 上编译,并进行了优化。
请不要使用 vector 回答,我知道这种可能性,但我对这种行为的更深层原因感兴趣......
编辑:
我已经阅读了 cmets,我的 class Array 进行了 2 次查找,我应该使用直接 1 次查找并返回对 double 的引用。我试过了,没有速度提升,完全一样。
而且我真的不明白为什么我的班级会进行 2 次查找:
Array arr(1000,1000);
arr[x][y] = n;
应该内联到:
(arr.data+x*arr.Y)[y] = n;
还有:
*((arr.data+x*arr.Y)+y) = n;
什么是完全一样的:
arr.data[x*arr.Y+y] = n; // the proposed 1 lookup access
我错了吗?
编辑2:
我再次计时并注意到,double **arr; arr[x][y] = n; 解决方案有不同的时间,从 1:47 分钟到 2:10 分钟 - 随机样式。
所有其他解决方案:
- 像上面那样封装
class Array -
double &operator() (int x, int y)喜欢建议 - 与普通
double *arr; arr[x*Y+y] = n;
实际上相同在 1:44 分钟左右快速并且始终保持不变。
【问题讨论】:
-
"... 比真正的二维更快一点" :您对此的评价完全相反。指向动态数据数组的指针的动态数组但是“真正的二维数组”。它与 real 二维数组
Type data[N][M]的唯一共同点是语法糖,生成的操作码的反汇编将向您展示这一点。您是正确的,具有单次查找的连续区域会更快;您的代码根本没有这样做(还)。我相信一些答案会证明这一点。 -
关于您对扩展的编辑是否相同:实际上是的,您设置它的方式应该是,因为您重载会改变括号的含义。因此,确实您的类数组解决方案应该与所有单查找解决方案一样快,而双 ** 方式的速度比您发现的要慢。可能值得查看您的分析测试,好像您没有对数组做太多事情,那么编译器可能会优化大部分测试,导致结果不准确(或者如果没有进行优化,那么测试是无用的对于现实世界)。
标签: c++ arrays optimization heap-memory