gpt4 book ai didi

c++ - 封装二维数组与普通版本——访问速度

转载 作者:行者123 更新时间:2023-11-28 03:01:25 41 4
gpt4 key购买 nike

这个问题是这个问题的延续: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 回答,我知道这种可能性,但我对这种行为的更深层原因感兴趣...

编辑:

我已阅读评论,我的 class Array 进行了 2 次查找,我应该使用直接 1 次查找并返回对 double 的引用。我已经试过了,但没有速度提升,完全一样。

而且我真的不明白为什么我的类(class)进行 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 分钟的不同时间 - 以随机方式。

所有其他解决方案:

  1. 像上面那样封装类数组
  2. 与建议的double &operator() (int x, int y)
  3. 使用普通 double *arr; arr[x*Y+y] = n;

实际上 相同 大约 1 分 44 秒,并且始终保持不变。

最佳答案

您没有获得性能优势,因为您仍然必须在包装版本中执行两次内存查找。仅访问元素 x*1000+y 的一维情况下的算术运算仅需要一次内存查找。您的包装版本返回一个指针,然后必须再次取消引用,这是缓慢的部分。

尝试将包装版本访问重铸为

inline double  operator()(int x, int y) const {return data[x*Y + y];}
inline double& operator()(int x, int y) {return data[x*Y + y];}

并调用为

arr(x,y) = n;

令我惊讶的是,封装的数组比普通的二维数组更快,因为它只会有更多的开销。

编辑:现在,通过更多地关注问题,我发现您的解决方案实际上并没有进行两次查找,因为您的重载 [] 运算符的行为不同。请参阅我对原始帖子的评论。

关于c++ - 封装二维数组与普通版本——访问速度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20747022/

41 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com