Iteration vs Recursion in Javascript

Anand B
The Startup
Published in
3 min readDec 6, 2020
Photo by Roman Synkevych on Unsplash

Introduction

There are many approaches to a single problem and we are always after the most efficient solution. Today, let us compare the performance between Iteration and Recursion.

Let us consider a simple problem — Given an array of strings, write a function to capitalize each array element.

I know all of your brain cells have started jumping in to solve it out. Yes, all of us will have a different approach to this. The one that came to my mind would be the one below. Simple and Short.

let capArr1 = (arr) => {
return arr.map((val) => val.toUpperCase());
}
capArr1(["Wolverine", "Ironman"]); //["WOLVERINE", "IRONMAN"]

Iteration

Most of us would agree that the straight forward solution to this would have been to use a loop and iterate over the items and capitalizing them. I have used a new variable deliberately here.

let capArr2 = (arr) => {
let newArr = [];
for (let i = 0; i < arr.length; i++) {
newArr.push(arr[i].toUpperCase());
}
return newArr;
}
capArr2(["Wolverine", "Ironman"]); //["WOLVERINE", "IRONMAN"]

Recursion

Some intrigued minds would love to use Recursion to solve this out. Now you probably know as to why I used a new variable to store my array, as I want my operations to be similar in both the approaches in order to compare the time taken for these functions to run.

let capArr3 = (arr) => {
if (arr.length === 1) {
return [arr[0].toUpperCase()];
}
let newArr = capArr3(arr.slice(0, -1));
newArr.push(arr.slice(-1)[0].toUpperCase());
return newArr;
}
capArr3(["Wolverine", "Ironman"]); //["WOLVERINE", "IRONMAN"]

Let us use performance.now() function to measure the time taken by each function and will increase the input array size to be able to identify the noticeable difference.

let veryLongArr = ["wolverine", "ironman", "captain america", "thor", "hulk", "black widow", "hawkeye", "black panther", "vision", "dr.strange", "antMan", "wasp", "spiderman", "scarlett witch", "quicksilver", "grrot", "star lord", "gamora", "rocket raccoon", "drax", "ms.marvel"] and so on.

I created an array of 100,00 elements by repeating these values repeatedly. Phew! Well not really, Array concat function helped me out. I created a new function that will take one of the above three functions and find the average time for 10 function executions.

let avgTime = (func, veryLongArr) => {
let timeArr = [],
n = 0;
while (n < 10) {
let t1 = performance.now();
func(veryLongArr);
let t2 = performance.now();
timeArr.push(t2 - t1);
n++;
}
console.log(timeArr);
return (timeArr.reduce((acc, val) => acc + val)) / 10
}
avgTime(capArr1, veryLongArr);
avgTime(capArr2, veryLongArr);
avgTime(capArr3, veryLongArr);
Chrome Performance Comparison
Mozilla Performance Comparision — performace.now() gets a rounded value in this browser

Final Thoughts

map and for are nearly comparable. A minor difference in performance is seen for a humongous dataset. map to me looks cleaner and is a great choice if we are sure to iterate over the entire data set in a straight order whereas in for loop you can influence the order and increment value.

On the other hand, Recursion is memory-hungry as each time it will push a memory address to the Call Stack. So it's better not to use recursion for performance reasons. We can use recursion to make the solution more simple and readable.

I would encourage writing code in such a manner that it is readable and understandable to the lad that is going to maintain your code for the upcoming years. Hope this has been insightful.

Until next time! :)

--

--

Anand B
The Startup

Software Developer-Android/React JS/ SAP UI5