How to Memoize any Function in Javascript | Memoization

Memoization is widely used programming technique which speeds up the execution of complex functions by caching the previously calculated results and returning the result directly from the cache when same input occurs. It is a commonly applied optimization technique across different frameworks as well.

How to Memoize any Function in Javascript | Memoization
How to Memoize any Function in Javascript | Memoization


For example you can consider a factorial function or any complex mathematical function. We can store its result in Cache which is a temporary storage. We will use a object here.

In order to implement memoization, you should be aware of closures and higher order functions which we used in ADD(1)(2)(3)...(N)() IN JAVASCRIPT | SUM(1,2)(3,4) | CURRYING  example. You can refer to this post to understand how currying works and how we use higher order functions. 

Closure gives the access to outer functions scope from inner function. It can access even after the outer function has returned. If you wan't me to cover this in details then post a comment or you can refer to many tutorials across the web. This is a very hot Javascript Interview Question as well.

With this knowledge, let's jump into our code. For example, we will consider a simple multiplication function. Although, memoization is advisable to only complex operations.

Let's write a function memoized that will return
the memoized function of multiply or
any other function.

var multiply = function(a,b) {
	return a*b
}

var memoized = function(foo){
var cache = {};
	return function(...args){
		var argId = args.toString();
		if(cache[argId]){
			return cache[argId]
		}else {
			var value = foo(...args);
cache[argId] = value
return value
}
}
}

Let's break it down,
  • Function memoized takes another function foo
  • cache is just an empty Javascipt Object
  • We are returning another function that will serve as memoized function
  • args is a parameter that handles the arguments of original function
  • Rest operator(...) allows us to accept infinite parameters i.e a , b in multiply function
  • We create a unique id combining all parameters
  • We check if that key has a value in cache object. If yes we return the value
  • Else we call original function with all arguments
  • Store the returned value in Cache and return the value.
  • Since we have created a closure, we can access cache object even after function has returned
Let's do the magic,
var memoizedMultiplier = memoized(multiply);
console.log(memoizedMultiplier(4,6)) // 24 from calculation
console.log(memoizedMultiplier(4,6)) // 24 from cache
Let's consider complex example of a factorial function that is recursive,
var factorial = function(n) {
    if (n <= 1) {
        return 1;
    }
    else {
      return n * factorial(n - 1);
    }
}
factorial = memoized(factorial)
console.log(factorial(5)) // 120 calculated
console.log(factorial(6)) // 720 ( 6 * 5 Factorial from cache )

Conclusion: I hope you liked my post on How to Memoize any Function in Javascript | Memoization.  This is how we can optimize any performance heavy function. Please comment if you want to share your solution. Memoization is also an important Javascript Interview Question which you should be aware of. 

Follow me on Twitter to if you want to discuss anything related to Javascript/Frontend Interviews. I will be happy to help.


Comments