bug*_*ugs 4 javascript arrays performance v8
最近,我不得不优化与创建大型数组(〜10?元素)有关的任务。
我测试了几种不同的方法,并且据jsperf所述,以下选项似乎是最快的。
var max = 10000000;
var arr = new Array(max);
for (let i = 0; i < max; i++) {
arr[i] = true;
}
Run Code Online (Sandbox Code Playgroud)
比〜快85%
var max = 10000000;
var arr = [];
for (let i = 0; i < max; i++) {
arr.push(true);
}
Run Code Online (Sandbox Code Playgroud)
实际上,在我的实际应用中,第一个代码片段的运行速度也要快得多。
然而,我的理解是,V8引擎能够进行优化的操作对数组PACKED_SMI_ELEMENTS的元素种类,而不是数组HOLEY_ELEMENTS。
所以我的问题是:
new Array(n)创建一个内部标记为的数组HOLEY_ELEMENTS(我相信是真的),并且[]创建一个内部标记有数组的数组PACKED_SMI_ELEMENTS(我不太确定是真的)为什么第一个摘要比第二个要快?
我经历过的相关问题:
V8开发人员在这里。第一个代码段速度更快,因为它new Array(max)告知V8您希望数组的大小,因此它可以立即分配大小合适的数组;而在带有[]/ 的第二个代码段中.push(),数组从零容量开始,必须增长几次,这包括将其现有元素复制到新的后备存储中。
https://www.youtube.com/watch?v=m9cTaYI95Zc是一个很好的演示,但是可能应该更清楚地说明打包元素和有孔元素之间的性能差异有多小,您应该为此而担心的很少。
简而言之:只要知道需要多大的数组,就可以使用new Array(n)将其预分配给该大小的方法。如果您事先不知道最终会有多大,则从一个空数组开始(使用[]或new Array()或new Array(0),无关紧要),然后根据需要增长它(使用a.push(...)或a[a.length] = ...,无关紧要)。
旁注:“使用新Array()和推入的for循环”基准测试创建的数组要大两倍。