Currently we use
Array.from({ length: n })
That's kind of verbose and a bit weird. I think we replaced Array(n).fill() with that, but there is also:
Array.from(Array(n))
[...Array(n)]
Which are nicer, I think.
In Chrome, the spread one is by far the fastest (10,000 iterations):
[...Array(1000)].map((_, i) => i)
// test: 512.635986328125ms
Array.from(Array(1000), (_, i) => i)
// test: 1093.662109375ms
Array.from({ length: 1000 }, (_, i) => i)
// test: 1252.54931640625ms
Array.from({ length: 1000 }).map((_, i) => i)
// test: 1302.962890625ms
It appears that using the second argument of Array.from() as the map instead of chaining .map offers almost no benefits in performance
I think we had a performance comparison and decided that Chrome is optimized for spread, but it's extremely slow on anything else.
In the same discussion, I think we decided to go with { length: n} for some reason, which I cannot remember. I definitely prefer it to Array(n).fill() and Array(n).from(Array(n)), but I'm not the only one with an opinion here, so let's vote on this (or someone could dig and find the original conversation on this topic).
I just tested Firefox (latest, mac) and spread is also faster. Not 2x like Chrome is but around 1.2x
I just run a JSPerf to check performance across multiple browsers. Here are my results on Windows 10:
The results are pretty clear here:
{ length: 1000 }, (_, i) => i are the two clear winners out of the bunch..map with length is slightly slower than using the second argument.So the question that arises is if we want to optimize for Chrome (around 80% of all users) and risk losing support for older browsers in a couple dozen snippets. I am not entirely set on either option, so any opinions would be useful here.
@fejes713, @skatcat31, @atomiks, @flxwu your thoughts?
To be honest all of these are fairly slow

The problem with all of the methods is that they all require the creation and deletion of internal memory addresses for every operation.
If you don't know your array size or needed array size all of these techniques are kind of moot.
If you don't need an extremely high performance application where every address matters, the none of these matter.
We should go for readability and maintainability over performance. Here readable brevity counts the most. To that end we should compare those metrics above performance since I doubt anyone will use these over a function that calls a for loop in a high performance application and if they're at the point they need to squeeze that much performance out of their application then they already know to make that change.
To that end my preference leans towards Array.from({ length: n }) for those specific segments PURELY because like a good program it reads like a story:
An Array from a defined length
An Array from a spread Array
An Array from an Array
Out of these the first story is the most cognitively easy to understand. If you told that to any developer they'd instantly know how to go about it. That's a huge win. Especially since Arrays of predefined length are such a rare occurrence.
@skatcat31 I really like the way you put this, that a good program should read like a story. I think we can stick with what we have as it doesn't have a huge impact in performance, is easy to read, doesn't harm compatibility etc. I'm closing for now, if spread somehow becomes faster over time across browsers, we can revisit this and see how we feel.
This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for any follow-up tasks.
Most helpful comment
To be honest all of these are fairly slow
The problem with all of the methods is that they all require the creation and deletion of internal memory addresses for every operation.
If you don't know your array size or needed array size all of these techniques are kind of moot.
If you don't need an extremely high performance application where every address matters, the none of these matter.
We should go for readability and maintainability over performance. Here readable brevity counts the most. To that end we should compare those metrics above performance since I doubt anyone will use these over a function that calls a for loop in a high performance application and if they're at the point they need to squeeze that much performance out of their application then they already know to make that change.
To that end my preference leans towards
Array.from({ length: n })for those specific segments PURELY because like a good programit reads like a story:Out of these the first story is the most cognitively easy to understand. If you told that to any developer they'd instantly know how to go about it. That's a huge win. Especially since Arrays of predefined length are such a rare occurrence.