javascriptarraysv8fillpacked

Does JavaScript's Array.prototype.fill() always create a packed array?


According to this discussion, once a JavaScript array becomes sparse at any point over the course of its lifetime, it forever remains holey. But if I were a V8 developer, I would probably optimize Array.prototype.fill() to always upgrade the underlying data structure to packed when called on its entirety e.g. Array(10).fill() because there's no reason why it can't and it doesn't add much overhead. (I know that setters and prototypal inheritance need to be taken into consideration but that's also the case with Array.prototype.push() which works on packed arrays.)

So my question is: does V8 in fact optimize holey arrays to become packed arrays in this one case where Array.prototype.fill() has been called on the entire length of the array? It's so easy to just create a new underlying packed array for its data structure before filling it with values. And if not then why not?


Solution

  • (V8 developer here.)

    The current state of things is that A.p.fill() never changes the holeyness/packedness of the array it operates on.

    Note that being "holey" is very different from being "sparse" (aka "in dictionary mode"). Holey arrays still have what you probably mean when you say "underlying packed array for its data structure" (I'd call it an "array-like backing store", as opposed to a "dictionary backing store").

    A.p.fill technically could mark arrays as packed, and perhaps it should, that's certainly been discussed. Reasons for the current behavior include:

    So, in summary: don't worry about it.