DEV Community

Cover image for Memoization in JavaScript? And how to apply it to get better code performance.
RakibRahman
RakibRahman

Posted on

Memoization in JavaScript? And how to apply it to get better code performance.

As a programmer, we always want to write code that is robust and gives us better performance. But sometimes we face performance issues due to not applying good optimization techniques. One such technique is Memoization. Memoization offers notable performance benefits when dealing with a function that has repeated parameters.
In this article, I'm going to talk about Memoization, how you can implement it and when it should be used.

Prerequisites

Before you begin reading, it will be great to know the followings:

So let's get started!!!

What is memoization?

From Wikipedia:

In computing, memoization or memoisation is an optimization technique used primarily to speed up computer programs by storing the results of expensive function calls and returning the cached result when the same inputs occur again.

So, Memoization is an optimization technique that can be used to reduce extensive(time-consuming) calculations by saving previous input to something called cache and returning the result from it. When a memoized function is given the same input again, it will return the cached result without calculating from the start. Thus saving code execution time and memory.

As you can guess, Memoization is not only limited to JavaScript but is also widely supported by many other languages. It's a common concept in the programming world.

Implementing Memoization

Before seeing how Memoization works, let's look at a simple example that will demonstrate how Memoization can help us to get better performance.
Consider the following function which returns the square of a number.

Normal Function

Image description
In case if you are not familiar with console.time() and console.timeEnd , they are used to track how long an operation takes. Read more about them on MDN.

Here, I've invoked the function with the same input four times. Here is its completion time:

time

Invocations Time Taken
First 9.331ms
Second 2.336ms
Third 1.397ms
Fourth 0.137ms

Later we'll compare this result against the memoized result.

Memoized Function

Now we are going to implement Memoization in the getSquare function. Remember that to memoize a function, it should be pure so that return values are the same for the same inputs every time.

Take a look at the following function:

normal function

Demo Output:

demo output

How Memoization works?

The principal to making a function memoized function is to store its last input and output. In JavaScript environment, Memoization heavily relies on Closure and Higher-Order Functions.

Code breakdown of memoSquare() function:

  • In line 3 we have variable named cache to store previous inputs.
  • In Line 5 we return the whole memoized function.
  • In Line 7 we check if the input is in the cache. If so, we return the cached value.cache can remember the values because of the closure it's implemented in. And this only works because the function we're working with is a pure function.
  • If we check the output of cache in line 9 of Output, we'll see that cache object is containing all the inputs only once.For example, We have inputted value 4 multiple times but it only storing it once. If the current inputted value is in the cache then it simply returns value. Check the Demo output screenshot.
  • From line 13 we write our function logic. In here it runs a for loop and simply returns a square of a number.
  • In line 15 we cache/store our new input value to the cache object.

Now lets checkout the completion time of memoSquare() function.

Invoking the function multiple times with same value:

result

Result:

memo function

Invocations Time Taken
First 7.741ms
Second 0.056ms
Third 0.52ms
Fourth 0.045ms

Normal function vs Memoized Function:

normal vs memoized

From the comparison table, you can see how Memoization grants us better performance aka execution time each time it is called with the same value. It cuts down the heavy calculations for a previous value. So it's a good idea to memoize a function that does heavy computations or is expensive on time and memory.

Use Cases

You can use Memoization in the following cases:

  • Repeated invocations of a function.
  • When you have a wide range of input values.
  • You have an idea what will be the possible inputs.
  • Functions that involves mathematically heavy operations.
  • In recursive functions.

Tradeoffs

Like any other optimization technique, There are limitations of Memoization. In some cases, improper use of Memoization can actually harm performance. Memoization works by storing old results and it has to be stored somewhere. As a consequence, memoized functions consume additional memory.
Memoization is appropriate for functions where there’s a high chance that the same input values will be used regularly. So Memoization may not be ideal for infrequently called or fast executing functions.

Third-party libraries for Memoization

You can use following third party libraries to implement Memoization:

References:

Followings are some resources to help you out:

Conclusion

Memoization is a form of caching which gives performance improvements where a function is called many times with the same input. Applying Memoization will help you to write performant and robust code. But you have to be careful about not implementing it in an irrelevant scenario.

That's all for today. Thank you for reading, and don't forget to connect on LinkedIn or Twitter

If you have any questions or thoughts, please leave a comment!?

Top comments (0)