代码之家  ›  专栏  ›  技术社区  ›  polygenelubricants

数组数组与多维数组的性能比较

  •  7
  • polygenelubricants  · 技术社区  · 15 年前

    当我在大学里使用C++时,我被告知要尽可能多地使用多维数组(MDA),因为它在一个大的块中表现出更好的内存位置。另一方面,数组数组(array of arrays,aoa)被分配成多个较小的块,可能散落在物理内存中找到空位的地方。

    所以我想第一个问题是:这是一个神话,还是一个值得遵循的建议?

    假设它是后者,那么下一个问题将是用Java这样的语言做什么,它没有真正的MDA。当然,用1da来模拟mda并不难。从本质上讲,对于有mda的语言,语法糖可以实现为对没有mda的语言的库支持。

    这值得努力吗?对于Java这样的语言来说,这是一个优化问题的过低水平吗?我们应该放弃数组并使用 List 甚至是原语?


    另一个问题:在Java中,一次分配AOA( new int[M][N] )可能产生不同于按层次结构执行的内存分配( new int[M][]; for (... new int[N] )?

    4 回复  |  直到 8 年前
        1
  •  3
  •   polygenelubricants    15 年前

    Java和C语言以与C++不同的方式分配内存。事实上,在.NET中,如果一个接一个地分配AOA的所有数组,那么它们肯定是紧密相连的,因为内存只有一个连续的块,没有任何碎片。

    但是对于C++来说仍然如此,如果你想要最大速度,仍然是有意义的。虽然你不应该在每次需要多维数组时都遵循这个建议,但是你应该先编写可维护的代码,如果速度慢的话,再对其进行分析,过早的优化是这个世界上所有罪恶的根源。

        2
  •  1
  •   Stephen C    15 年前

    这值得努力吗?对于Java这样的语言来说,这是一个优化问题的过低水平吗?

    一般来说,这不值得努力。最好的策略是在应用程序的第一个版本中忘记这个问题,并以一种直截了当(即易于维护)的方式实现。如果第一个版本对于您的需求运行得太慢,请使用分析工具来查找应用程序的瓶颈。如果分析表明数组数组可能是问题所在,那么做一些实验,将数据结构更改为模拟多维数组,并分析它是否会产生显著差异。[我想这没什么区别。但最重要的是不要浪费时间去优化一些不必要的东西。]

    我们应该放弃数组,甚至对原语使用列表吗?

    我不会走那么远的。假设您正在处理预定大小的数组:

    • 对象数组将比等效的对象列表快一点,并且
    • 基元数组将比基元包装器的等效列表快得多,占用的空间也少得多。

    另一方面,如果您的应用程序需要“扩展”数组,那么使用列表将简化代码。

        3
  •  0
  •   Thomas Eding    15 年前

    我不会浪费在Java中使用1D数组作为多数组的努力,因为没有语法帮助。当然,可以定义函数(方法)来隐藏工作,但在使用数组数组时,只需调用函数而不是跟随指针。即使编译器/解释器为您加快了速度,我仍然认为这不值得付出努力。此外,当试图使用期望作为数组数组的2d(或n-dim)数组的代码时,可能会遇到复杂的情况。我相信大多数通用代码都会在Java中为这样的数组编写。也可以廉价地重新分配行(或者列,如果您决定这样想的话)。

    如果你知道这个多维数组是一个瓶颈,你可以忽略我所说的,看看手动优化是否有帮助。

        4
  •  0
  •   William Royle    12 年前

    从Java的个人经验来看,如果一个数组加载大量数据,或者访问处于不同位置的数据中的元素,多维数组远比一维数组慢得多。我写了一个程序,以bmp格式截取一个屏幕截图,然后在屏幕截图中搜索一个较小的图像。将屏幕截图图像(大约3 MB)加载到多维数组(三维,[xpos][ypos][color](color=0为红色值,suchforth))需要14秒。将它加载到一维数组需要1秒。 在大图像中找到小图像的增益是相似的。当两幅图像都存储为多维数组时,在较大的图像中找到较小的图像大约需要28秒。当两幅图像都存储为一维数组时,在较大的图像中找到较小的图像需要大约一秒钟的时间。也就是说,为了可读性,我首先使用维度数组编写了程序。