11

for the moment i use this JavaScript to create an array with n numbers from 0 to n

// javascript populate array 
var n=1000;
var arr=[n];
for (i=n;i>=0;i--) {
arr[i]=i;
console.log(arr[i]);
} 

is it the fast/right way to do the task?

1
  • for n=100000; got 15ms. Commented Apr 9, 2019 at 5:34

9 Answers 9

28

You can do declarative approach by using Array.from like this:

let arr = Array.from({length: 20}, (e, i)=> i)
console.log(arr)

Sign up to request clarification or add additional context in comments.

4 Comments

merely as fast as cycle iteration method 25 vs 15. ms with n=100000
Can you expand on how this works? I've read the MDN documentation but need an ELI5. How does {length: 20} work and how do I look this up?
@pmath325 Under Description on MDN: array-like objects (objects with a length property and indexed elements). You create a new Object with a length property as required (i.e.-20): Array.from looks at that length property and tries to index the Object for each index in length (0...19). It gets Undefined as the value at each index, and passes (Value,Index) to the arrow function. The arrow function then returns the Index, which is collected by Array.from.
this is the slowest method though
8

An ES6 way of doing it using Array.keys():

let n = 10;
let arr = Array.from(Array(n).keys());

console.log(arr);


Made a quick JSPerf with answer so far:

https://jsperf.com/array-filling-so/

1 Comment

there is big dispersion of duration time value from 19ms to 50ms. but that is merely fast method. (n=1000000);
8

If by efficient you mean ‘least number of characters’, I think this is shorter than any of the answers posted:

[...Array(10).keys()]

Things like this come in handy when testing stuff using the browser console. Be warned though that it's more than twice as slow as the currently accepted answer of:

Array.from({length:10},(e,i)=>i)

Although I haven't professionally tested the performance, I tried creating an array with 1e8 elements using both methods and it took about five seconds using the first method and just two using the second method (with considerable variability for both methods) on my little laptop whereas an array with 1e9 elements caused it to run out of memory.

But for people who need to enter stuff like this into the browser console regularly, that might not matter as much as ease of remembrance and entry. Note however that if you're going to feed the result immediately into a .map() the first method is only one character shorter and the performance will be even worse in comparison, particularly because the second method doesn't need a separate .map() call. So, only for debugging or trying stuff out, but still useful in my opinion.

Comments

3

You can use the function map skipping the first param of the predicate and getting the index i.

let arr = Array(10).fill().map((_, i) => i);
console.log(arr);

1 Comment

short, but slow.~35ms vs 15ms
2

Array.from(Array(1000).keys()); Is the fasted so far in v8 engine. Dont listent other. https://jsbench.me/jdjxrdszul/2

1 Comment

[...Array(1000)].map((a,b)=>b) seems to be almost twice as fast.
1

The shortest way (I think) [...Array(10)].map((a,b)=>b)

console.log(
  [...Array(10)].map((a,b)=>b)
)

Comments

1

If you are looking for the fastest method, don't use any ES6 methods, they are shorter, but almost always the slowest. In almost every situation a simple for loop is the fastest method:

const arr = Array(1000);
for(let i = 0; i < arr.length; i++)
  arr[i] = i;

https://jsbench.github.io/#52f84c5cfe44859b4bcba661ea3dd254

* note, the base code from the question produces array of 1001 numbers, while all other examples produce 1000 enter image description here

Comments

0

Slightly optimized by using a while loop:

let i = 1000;
const arr = [0];
while (i) {
  arr[i] = i;
  i--;
}

enter image description here

Comments

0

You can use the following code to benchmark these methods. This code runs each method 100 times and calculates the minimum, maximum, average, and median times for each method:

const quantity = 1e5;
const runs = 100;

function runBenchmark(func, name) {
  const times = [];
  for (let i = 0; i < runs; i++) {
const start = performance.now();
func();
const end = performance.now();
times.push(end - start);
  }
  return times;
}

function calculateStats(times) {
  times.sort((a, b) => a - b);
  const min = times[0];
  const max = times[times.length - 1];
  const sum = times.reduce((acc, time) => acc + time, 0);
  const avg = sum / times.length;
  const median = times.length % 2 === 0 ? (times[times.length / 2 - 1] + times[times.length / 2]) / 2 : times[Math.floor(times.length / 2)];
  return { min, max, avg, median };
}

function testWhileLoop() {
  const arrayWhile = [];
  let i = 1;
  while (i <= quantity) {
arrayWhile.push(i);
i++;
  }
}

function testLoopWithPush() {
  const arrayPush = [];
  for (let i = 1; i <= quantity; i++) {
arrayPush.push(i);
  }
}

function testArrayFromWithMapping() {
  Array.from({ length: quantity }, (_, i) => i + 1);
}

function testArrayFromWithKeys() {
  Array.from(Array(quantity).keys(), x => x + 1);
}

function testFillAndMap() {
  new Array(quantity).fill(0).map((_, i) => i + 1);
}

function testReduce() {
  Array(quantity).fill(0).reduce((acc, _, i) => {
acc.push(i + 1);
return acc;
  }, []);
}

const whileLoopTimes = runBenchmark(testWhileLoop, 'While loop');
const loopWithPushTimes = runBenchmark(testLoopWithPush, 'Loop with push');
const arrayFromWithMappingTimes = runBenchmark(testArrayFromWithMapping, 'Array.from with mapping');
const arrayFromWithKeysTimes = runBenchmark(testArrayFromWithKeys, 'Array.from with keys');
const fillAndMapTimes = runBenchmark(testFillAndMap, 'Fill and map');
const reduceTimes = runBenchmark(testReduce, 'Reduce');

const whileLoopStats = calculateStats(whileLoopTimes);
const loopWithPushStats = calculateStats(loopWithPushTimes);
const arrayFromWithMappingStats = calculateStats(arrayFromWithMappingTimes);
const arrayFromWithKeysStats = calculateStats(arrayFromWithKeysTimes);
const fillAndMapStats = calculateStats(fillAndMapTimes);
const reduceStats = calculateStats(reduceTimes);

console.log('While loop stats:', whileLoopStats);
console.log('Loop with push stats:', loopWithPushStats);
console.log('Array.from with mapping stats:', arrayFromWithMappingStats);
console.log('Array.from with keys stats:', arrayFromWithKeysStats);
console.log('Fill and map stats:', fillAndMapStats);
console.log('Reduce stats:', reduceStats);

Local executions in both Node and Firefox led to these observations:

  • While Loop: Consistently one of the fastest methods.
  • Loop with Push: Also very efficient and close to the while loop in performance.
  • Array.from with Mapping: Moderately efficient but slower than the loops.
  • Array.from with Keys: Moderately efficient but slower than the loops.
  • Fill and Map: Relatively efficient but slightly slower than the loops.
  • Reduce: Moderately efficient but not as fast as the loops.

Conclusion

Based on the benchmark results, the while loop and the for loop with Array.push are the most efficient methods for creating an array filled with a range of numbers.

Methods using only expression like map and reduce allows to provide compactest functions for example with a single return statement, while those relying on loop statements require a bit more of verbosity. There is not more than a single order of magnitude observed in performance differences while running this benchmark in local.

Treating less than 100 items took at most a single digit millisecond in my own tests, and the shortest perceivable application response delay varies depending on which perception channel is implicated: as a rule of thumb under 10ms is OK for sound and 100ms for visual responses. But of course, this only matter if the function at hand is actually the big elephant in the room caught through performance tests.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.