Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Javascript performance: reduce() vs for-loop

I was attempting this Codewars challenge and the problem involves finding the divisors of a number and then calculating the sum of these divisors squared. I found two approaches to this problem.

The first approach is based on another Stackoverflow questions about finding the sum of all divisors and seems clever at first:

function divisorsSquared(n) {
  // create a numeric sequence and then reduce it
  return [...Array(n+1).keys()].slice(1)
   .reduce((sum, num)=>sum+(!(n % (num)) && Math.pow(num,2)), 0);
}

The second approach I used was using a simple for-loop:

function divisorsSquared(n) {
  var sum = 0;
  for(var i = 1; i<= n; i++){
     if(n % i === 0) sum += Math.pow(i,2); 
  }
  return sum;
}

Now I noticed that the first approach is significantly slower than the second and a quick jsperf test confirms this.

My questions are: Why is the first approach so much slower and what approach is preferable in production code?

On Codewars I notice that for many challenges there are clever one-line solutions using similar array methods. As a beginner, may such solutions be considered better practice than for-loops, even if performance is worse?

like image 371
Miguel G. Avatar asked Apr 22 '17 06:04

Miguel G.


People also ask

Is reduce faster than for loop Javascript?

a + x. b, 0); Both for and for..of are 3.5 times faster than reduce .

What is faster than for loop in Javascript?

forEach loop The forEach method in Javascript iterates over the elements of an array and calls the provided function for each element in order. The execution time of forEach is dramatically affected by what happens inside each iteration. It is fast and designed for functional code.

What is faster than a for loop?

List comprehensions are faster than for loops to create lists. But, this is because we are creating a list by appending new elements to it at each iteration.

Is map () faster than for loop?

map() works way faster than for loop. Considering the same code above when run in this ide.


2 Answers

  • Array(n+1) allocates an array with n + 1 elements, Array(n+1).keys() returns an iterator over the created array's indices, but the spread operator [...Iterator] helps "unwrap" this iterator into yet another array, then finally slice(1) comes along to copy the secondly created array starting at index 1 which allocates yet another array (third one) with the number 0 discarded. So that were 3 allocations but 2 were dicarded. Your for-loop does not allocate any arrays, it is a simple traversal in O(n) with only 2 allocations for i and sum, so it is more efficient
  • sum+(!(n % (num)) && Math.pow(num,2)) is essentially the same as if(n % i === 0) sum += Math.pow(i,2); but the if approach is way more readable. If I were the judge, I would pick the second approach because it is more memory efficient, yet it favors readability.
like image 179
Meme Composer Avatar answered Oct 24 '22 01:10

Meme Composer


Looking into the code, for loop is obviously less complex and more readable.

Consider you are working within a team, maximum number of your team members will know what the code is doing right away. Some will have to look up what the reduce() method is, but then they'll also know what's going on. So here, a for loop is easier for others to read and understand.

On the other side, native array functions (filter(), map(), reduce()) will save you from writing some extra code and also slower in performance.

For a beginner, I think for-loops should be better over native array functions.

like image 36
Mamun Avatar answered Oct 24 '22 01:10

Mamun