So from what I remember, Array implementations in V8 come in two flavours: Fast element and Dictionary element (hash table) arrays. The former is present when the array is below 10000 elements and doesn't have any "holes" in them. The latter, on the other hand, is present when the opposite is true: array.length > 10000 and array has "holes" (e.g. [1, 2, undefined, 4, 5])
So concat might have been slow because of this reason. I'm still not certain about this, mainly because .push was still fast.
While not shown in the use case (as the above oversimplifies the actual code). Your right that holes have an impact between the array mode / dictionary mode in V8 code. Having holes does not gurantee a trigger into dictionary mode, but is one of the contributing factor in how the internal engine decides the mode.
Probably worth further investigation, gut feel as of now from how I understand it, is the array in our use case would not have any holes 99% of the time. And from our internal code monitoring, its these 99% that's has the problem. >_<
I can't recall the talk reference for this (but definitely know it's real) so if you know where it's from. It would be good to add here for others to learn.
I replied to this, but I don't see the reply here. Really weird.
Anyways here are two resources that talk about how V8 handles arrays:
We're a place where coders share, stay up-to-date and grow their careers.
We strive for transparency and don't collect excess data.