【问题标题】:Representing a 2D array as a 1D array [duplicate]将二维数组表示为一维数组[重复]
【发布时间】:2010-11-29 19:12:24
【问题描述】:

可能的重复:
Implementing a matrix, which is more efficient - using an Array of Arrays (2D) or a 1D array?
Performance of 2-dimensional array vs 1-dimensional array

前几天我正在查看我朋友的一个分子动力学代码库,他将一些二维数据表示为一维数组。因此,他不必使用两个索引,只需要跟踪一个索引,但需要进行一些数学运算来确定如果它是 2D 它将处于什么位置。所以在这个二维数组的情况下:

two_D = [[0, 1, 2],
         [3, 4, 5]]

它可以表示为:

one_D = [0, 1, 2, 3, 4, 5]

如果他需要知道二维数组的 (1,1) 位置是什么,他会做一些简单的代数并得到 4。

使用一维数组而不是二维数组是否有任何性能提升。数组中的数据在计算过程中可以被调用数百万次。

我希望数据结构的解释清楚......如果不让我知道,我会尝试更好地解释它。

谢谢你:)

编辑 语言是C

【问题讨论】:

标签: c performance arrays


【解决方案1】:

通常二维数组被实现为一维数组。有时,二维数组是由一维数组的指针组成的一维数组实现的。与一维数组相比,第一种情况显然没有性能损失,因为它与一维数组相同。由于额外的间接性(以及缓存局部性降低等其他微妙影响),第二种情况可能会带来轻微的性能损失。

每个系统使用哪种类型是不同的,因此如果没有有关您正在使用的信息的信息,真的无法确定。如果它对你真的很重要,我建议只测试性能。如果性能不是那么重要,那就不用担心了。

对于 C,2D 数组是带有语法糖的 1D 数组,因此性能是相同的。

【讨论】:

    【解决方案2】:

    【讨论】:

    • 注意:引用的 SO 问题与 C 语言有关。
    【解决方案3】:

    您没有提到这是关于哪种语言或如何实现二维数组。在 C 中,二维数组实际上是作为一维数组实现的,其中 C 自动对索引执行算术以访问正确的元素。所以它会做你朋友在幕后做的事情。

    在其他语言中,二维数组可能是指向内部数组的指针数组,在这种情况下,访问元素将是数组查找 + 指针取消引用 + 数组查找,这可能比索引算法慢,尽管它不会除非您知道这是一个瓶颈,否则值得优化。

    【讨论】:

      【解决方案4】:
      oneD_index = 3 * y + x;
      

      其中 x 是行中的位置,y 是列中的位置。而不是 3 你使用你的列宽。这样您就可以将 2D 坐标转换为 1D 坐标。

      【讨论】:

      • 没错,但如何计算指数不是问题。
      【解决方案5】:

      对于宽度为 W 和高度 H 的二维数组,您可以将其表示为长度为 W*H 的一维数组,其中每个索引

       (x,y)
      

      其中x是列,y是行,二维数组映射到索引

      i=y*W + x
      

      在一维数组中。同样,您可以使用逆映射:

      y = i / W
      x = i % W
      

      。如果您将 W 设为 2 的幂 (W=2^m),则可以使用 hack

      y = i >> m;
      x = (i & (W-1))
      

      这种优化仅限于 W 是 2 的幂的情况。编译器很可能会错过这种微优化,因此您必须自己实现它。

      Modulus 在 C/C++ 中是一个缓慢的运算符,所以让它消失是有利的。

      此外,对于大型二维数组,请记住计算机将它们作为一维数组存储在内存中,并且基本上使用我上面列出的映射来计算索引。

      比确定这些映射的方式更重要的是如何访问数组。有两种方法可以做到这一点,列专业和行专业。您遍历的方式比任何其他因素更重要,因为它决定了您是否使用 缓存 来发挥自己的优势。请阅读http://en.wikipedia.org/wiki/Row-major_order

      【讨论】:

      • 再说一遍,这不是问题。
      • +1 以获得如此好的回应!我知道这是 [许多] 年的历史,但仍然是非常有价值的信息。谢谢,@ldog
      猜你喜欢
      • 2014-04-23
      • 2018-02-09
      • 2011-02-28
      • 2013-01-27
      • 2011-07-26
      • 1970-01-01
      • 1970-01-01
      • 2023-04-11
      • 2020-05-06
      相关资源
      最近更新 更多