最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How does V8 optimise the creation of very large arrays? - Stack Overflow

programmeradmin1浏览0评论

Recently, I had to work on optimising a task that involved the creation of really large arrays (~ 10⁸ elements).

I tested a few different methods, and, according to jsperf, the following option seemed to be the fastest.

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

Which was ~ 85% faster than

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

And indeed, the first snippet was much faster in my actual app as well.

However, my understanding was that the V8 engine was able to perform optimised operations on array with PACKED_SMI_ELEMENTS elements kind, as opposed to arrays of HOLEY_ELEMENTS.

So my question is the following:

  • if it's true that new Array(n) creates an array that's internally marked with HOLEY_ELEMENTS, (which I believe is true) and
  • if it's true that [] creates an array that's internally marked with PACKED_SMI_ELEMENTS (which I'm not too sure is true)

why is the first snippet faster than the second one?

Related questions I've been through:

  • Create a JavaScript array containing 1...N

  • Most efficient way to create a zero filled JavaScript array?

Recently, I had to work on optimising a task that involved the creation of really large arrays (~ 10⁸ elements).

I tested a few different methods, and, according to jsperf, the following option seemed to be the fastest.

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

Which was ~ 85% faster than

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

And indeed, the first snippet was much faster in my actual app as well.

However, my understanding was that the V8 engine was able to perform optimised operations on array with PACKED_SMI_ELEMENTS elements kind, as opposed to arrays of HOLEY_ELEMENTS.

So my question is the following:

  • if it's true that new Array(n) creates an array that's internally marked with HOLEY_ELEMENTS, (which I believe is true) and
  • if it's true that [] creates an array that's internally marked with PACKED_SMI_ELEMENTS (which I'm not too sure is true)

why is the first snippet faster than the second one?

Related questions I've been through:

  • Create a JavaScript array containing 1...N

  • Most efficient way to create a zero filled JavaScript array?

Share Improve this question asked Feb 1, 2019 at 14:54 bugsbugs 15.4k5 gold badges53 silver badges55 bronze badges 3
  • 3 IIRC packed vs holey isn't that much of a performance difference, it's just an internal marker that the array needs to be treated differently (especially given that many things changed in V8 since that talk). Also, the performance difference should be observed in using the array, not in creating and initialising it. What exactly did you benchmark, your whole app or only the two snippets you posted? – Bergi Commented Feb 1, 2019 at 14:59
  • @Bergi thanks, do you have any link to some documentation about this? In terms of benchmark, I measured the performance of a function that involved the creation and the usage of the array (the latter being the same in both cases) – bugs Commented Feb 1, 2019 at 15:03
  • 1 I found the link to one of @jmrk's answers: stackoverflow./a/53161007/1048572 (see the ments for discussion of holey vs packed). Not sure whether that question is duplicate-worthy. – Bergi Commented Feb 1, 2019 at 15:08
Add a ment  | 

1 Answer 1

Reset to default 13

V8 developer here. The first snippet is faster because new Array(max) informs V8 how big you want the array to be, so it can allocate an array of the right size immediately; whereas in the second snippet with []/.push(), the array starts at zero capacity and has to be grown several times, which includes copying its existing elements to a new backing store.

https://www.youtube./watch?v=m9cTaYI95Zc is a good presentation but probably should have made it clearer how small the performance difference between packed and holey elements is, and how little you should worry about it.

In short: whenever you know how big you need an array to be, it makes sense to use new Array(n) to preallocate it to that size. When you don't know in advance how large it's going to be in the end, then start with an empty array (using [] or new Array() or new Array(0), doesn't matter) and grow it as needed (using a.push(...) or a[a.length] = ..., doesn't matter).

Side note: your "for loop with new Array() and push" benchmark creates an array that's twice as big as you want.

发布评论

评论列表(0)

  1. 暂无评论