【问题标题】:How does V8 optimise the creation of very large arrays?V8 如何优化超大数组的创建?
【发布时间】:2019-02-01 14:54:38
【问题描述】:

最近,我不得不优化一项涉及创建非常大的数组(约 10⁸ 个元素)的任务。

我测试了few different methods,根据 jsperf,以下选项似乎是最快的。

var max = 10000000;
var arr = new Array(max);
for (let i = 0; i < max; i++) {
  arr[i] = true;
}

这比 85% 快

var max = 10000000;
var arr = [];
for (let i = 0; i < max; i++) {
  arr.push(true);
}

确实,第一个 sn-p 在我的实际应用中也快得多。

但是,我的理解是带有PACKED_SMI_ELEMENTS 元素的数组上的V8 engine was able to perform optimised operations 类型,而不是HOLEY_ELEMENTS 的数组。

所以我的问题如下:

  • 如果new Array(n) 确实创建了一个内部标有HOLEY_ELEMENTS 的数组(我相信这是真的)并且
  • 如果[] 确实创建了一个内部标记为PACKED_SMI_ELEMENTS 的数组(我不太确定是不是真的)

为什么第一个 sn-p 比第二个快?

我遇到过的相关问题:

【问题讨论】:

  • IIRC 打包与孔洞并没有太大的性能差异,它只是一个内部标记,需要对数组进行不同处理(特别是考虑到自那次谈话以来 V8 中发生了许多变化)。此外,应该在 使用 数组时观察性能差异,而不是在创建和初始化它时。您究竟对什么进行了基准测试,您的整个应用程序还是仅您发布的两个 sn-ps?
  • @Bergi 谢谢,你有关于这方面的一些文档的链接吗?在基准方面,我测量了一个函数的性能,该函数涉及数组的创建和使用(后者在两种情况下都是相同的)
  • 我找到了@jmrk 的答案之一的链接:stackoverflow.com/a/53161007/1048572(请参阅 cmets 以了解空洞与打包的讨论)。不确定该问题是否值得重复。

标签: javascript arrays performance v8


【解决方案1】:

V8 开发人员在这里。第一个 sn-p 更快,因为new Array(max) 通知 V8 你希望数组有多大,所以它可以立即分配一个正确大小的数组;而在带有[]/.push() 的第二个 sn-p 中,数组从零容量开始并且必须增长多次,其中包括将其现有元素复制到新的后备存储。

https://www.youtube.com/watch?v=m9cTaYI95Zc 是一个很好的演示文稿,但可能应该更清楚地说明打包元素和多孔元素之间的性能差异有多小,以及您应该担心的程度有多大。

简而言之:当您知道需要多大的数组时,使用new Array(n) 将其预分配到该大小是有意义的。当你提前知道它到底会有多大时,然后从一个空数组开始(使用[]new Array()new Array(0),没关系)并根据需要进行扩展(使用a.push(...)a[a.length] = ...,没关系)。

旁注:您的“for loop with new Array() and push”基准测试创建了一个比您想要的大两倍的数组。

【讨论】:

  • 很高兴直接从 V8 开发人员那里得到答案,感谢您的澄清。关于这一切,我可以查看任何文章/文档吗?并感谢您指出 jsperf 中的错误,我这边的小疏忽
  • @bugs:v8.dev 上的博客和文档包含大量信息,然后 YouTube 上有各种技术演示视频,您至少已经找到其中一个 ;-)跨度>
  • @vsemozhetbyt:正确,这是一个相关的功能请求;它的优先级很低,因为对于大多数实际代码来说,区别并不重要。
  • @jmrk new Array(n) 也会让您的阵列处于 HOLEY 模式。这不是被视为不好的做法吗?
  • @snek:使用new Array(n) 非常好,这不是一个坏习惯。 HOLEY模式没什么好担心的(见我回答的第二段)。将其视为“对于好奇的人来说,这是 V8 在后台执行的许多技巧之一,以从您扔给它的任何代码中挤出尽可能多的性能”。不要将其视为必须注意和避免的事情。
猜你喜欢
  • 2023-04-07
  • 1970-01-01
  • 2019-05-31
  • 2011-12-23
  • 2013-08-30
  • 2018-09-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多