2D阵列:首选方式访问项目

时间:2011-09-17 21:21:19

标签: java c++ c coding-style

所以我今晚在这个问题出现在脑海中:

您最喜欢的方式是访问m x n矩阵的项目

您可以使用索引作为列的常规方法 行矩阵[i] [j]

的另一个索引

还有另一种方法,你的矩阵是长度为m * n的向量 并使用[i * n + j]作为索引号

访问项目

告诉我你最喜欢什么方法,有没有其他方法 那对特定情况有用吗?

5 个答案:

答案 0 :(得分:1)

假设我们有这段C(++)代码:

 int x = 3;
 int y = 4;

 arr2d[x][y]   = 0xFF;
 arr1d[x*10+y] = 0xFF;

其中:

 unsigned char arr2d[10][10];
 unsigned char arr1d[10*10];

现在让我们看看它的编译版本(程序集;使用调试器):

enter image description here

正如您所看到的,无论您是否使用2D数组,访问数组元素时都绝对不会受到惩罚或减速,因为这两种方法实际上都是相同的。

答案 1 :(得分:0)

我不认为你最喜欢的方式,或者最美观的方式是采用这个问题的好方法 - 潜在的表现将是我的主要关注点。

将矩阵存储为连续数组通常是进行矩阵计算的最有效方法。如果你看一下优化的BLAS(基本线性代数子程序)库,比如英特尔MKL,AMD ACML,ATLAS等等,将使用连续的矩阵存储。当使用连续存储,并且利用连续数据访问模式时,由于操作的参考局部性(即高速缓存性能)得到改善,可能导致更高的性能。

在某些语言(即c++)中,您可以使用运算符重载来实现data[i][j]索引样式,同时在幕后执行一维数组索引映射。

希望这有帮助。

答案 2 :(得分:0)

只有两个理由可以让一维数组表示我能想到的n维:

  • 性能:分配n维数组的常用方法意味着我们得到的n个维度可能不一定分成一个部分 - 这对于空间局部性来说并不是那么好(并且也可能至少导致一些额外的内存访问 - 在最坏的情况下,每次访问需要额外的1次读取。现在用C / C ++你可以解决这个问题(在一个部分中分配内存,然后指定正确的指针;在删除它时要非常小心不要忘记这个)并且其他语言(C#)已经能够实现这一点。框。另请注意,在具有停止和复制GC的语言中,推理是不必要的,因为无论如何所有对象将彼此分配。但是,您可以避免每个维度的额外开销,因此您可以更好地使用内存和缓存。

  • 对于某些算法,使用一维数组会更好,这可能会使代码更短,速度更快 - 这可能是一件可以被认为是主观的事情。

答案 3 :(得分:0)

我认为如果你需要一个2D数组,是因为你想将它作为二维数组访问,而不是作为一维数组

否则你可以做一个简单的乘法使它成为一维数组

答案 4 :(得分:0)

如果我要使用二维数组,我会投票支持矩阵[i] [j]。我认为这更具可读性。但是,我可能会考虑使用Guava的Table类。 http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/common/collect/Table.html