【问题标题】:Efficiency: Objects inside arrays or arrays inside objects?效率:数组中的对象还是对象中的数组?
【发布时间】:2015-12-15 02:54:04
【问题描述】:

给定相同数量的数组/对象层,每个索引表示相同的东西,嵌套数组和对象的最佳顺序是什么?

我正在制作一个基于网格的游戏,我需要存储关于每个方格的几条信息。我知道没有绕过多个级别的数组/对象。我已经让它以一种方式工作,所以在我更改大量代码之前(我至少有 5 个函数,每个函数内部都有一个沉重的 switch 语句(选择我们正在使用的层),并且也许还有 10 个我还必须更改,连同初始化函数),我想知道这种更改是否真的符合最佳实践。

目前,我的布局是这样的:Game.grid.map[x][y][layer][direction],所以一个带有常规二维数组的地图,每个元素都是一个对象,包含 "V","S","M" 的属性和“G”,每个都包含一个数组。 (金属、硅、栅极和通孔)

我正在考虑切换到Game.grid.map[layer][x][y][direction] 我将不得不更改一些结构(例如我有var base = this.map[x][y]; 然后使用base[layer][dir] 但我可以轻松地进行此更改并使用变量baseM,baseG , 和 baseS。更改它只是乏味。我想知道让 1 个对象和 5 个大数组而不是让大型 2D 数组和许多非常小的对象更有效。

我在某处读到,在纯数组中,这取决于索引在每个级别上更改的频率,外部级别更改得更慢。这样,改变它是有意义的。我倾向于同时处理所有金属,同时处理所有通孔,以及硅和盖茨一起处理(ish)。

搜索 Google 将我带到了这个 QA:Fastest way to read/store lots of multidimensional data? (Java) 但这仅处理纯数组,而不是对象和数组的混合

===编辑===

1) 是的,我错过了我找到的那个 QA 是 java 而不是 javaScript。

2) 我稍微修改了他们的测试。

var arr = [];
for (int x=0; x<100; x++){
    arr[x] = [];
    for (int y=0; y<100; y++){
        arr[x][y] = [];
        for (int z=0; z<100; z++){
             arr[x][y][z] = 1;
        }
    }
}

这大约需要 10 毫秒。 (通过将函数粘贴到控制台并从“未定义”时间戳中减去该时间戳来测量。)在使顶层成为对象和使底层成为一堆对象之间,也是 10 毫秒。制作所有关卡对象需要 9 毫秒。这让我很惊讶。但这也意味着贝尔吉是对的。没关系。我担心现有对象的绝对数量,但如果 10,000 个新对象花费不到 10 毫秒,那么我的 400 个对象网格不应该成为问题。

因此,实际上唯一的效率变化是读取/写入以每种方式标记的代码需要多长时间。对我来说,在这个上避免并行数组肯定更容易。 (我没有意识到这个问题是关于微优化的。)谢谢所有回答的人。

【问题讨论】:

  • 我会等到你实现了你能找到的最有效的高级算法后再考虑这个问题。在您确定糟糕的算法选择不是 90% 的性能问题的根源之前,像这样的微优化是浪费时间。
  • 此外,JavaScript 中的属性查找通常在任何情况下都经过高度优化。这是所有 JavaScript 代码中的基本操作。
  • Java 的低级运行时效率也与 JavaScript 没有任何关系。
  • 最后一个就是为什么必须问这个问题。我可以在 Google 上轻松找到 JavaScript 中的这些内容。我发现的其他 QA 是那些一开始不知道如何编写对象的人。
  • 为什么需要二维数组?如果您正在使用网格,则可以使用一维数组并跟踪行发生的位置。这样一来,每个网格方块都有一个索引,处理寻址的数学不仅简单,而且 JavaScript 处理得非常快。

标签: javascript arrays object micro-optimization


【解决方案1】:

阅读多维数组的parallel arraysmajor order。理论上,您可以从缓存位置获得一些速度,这取决于您通常如何访问数组。

在实践中,尤其是在像 JS 这样的解释型语言中,这并不重要(首先还有很多其他方面需要优化)。选择对你最有意义的东西,并坚持下去。

【讨论】:

    【解决方案2】:

    你在说多少个对象?正如@Bergi's answer 所提到的,在您踏上这条路之前,还有很多很多需要优化。从技术上讲,在迭代期间通过索引访问数组可能会稍微快一些,这要感谢通过属性的对象,即使那样它也取决于 JS 引擎的实现,在数组数组这样的紧张情况下可能会有很大差异。

    此外,根据对象的剪切数量,您可能会遇到内存限制。最后,在您最关心支持的浏览器中进行测试。这就是它可以归结为的全部。避免一次循环过多的项目(一旦超过 10k 左右,它可能会打嗝,超过一百万,你可能会遇到问题)。

    【讨论】:

    • 数组的迭代速度可以稍微快一点”是什么意思?那又如何?不,这与大小是否“预先声明”无关。
    猜你喜欢
    • 2011-04-19
    • 1970-01-01
    • 2013-06-22
    • 1970-01-01
    • 2018-03-01
    • 1970-01-01
    • 2011-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多