Memoization in JavaScript
Short read to describe the optimization technique of Memoization in JavaScript.
Hello folks! In this blog I would like to put forth my understanding of memoization in Javascript. We are aware that memoization is an optimization technique which basically saves from expensive transactions such as API calls and Heavy computation function calls, but do we know how it works under the hood!? Let's take an look!
Memoization, what is it?
"Memoization is an optimization technique in Javascript which includes caching and basically avoids expensive functional calls based on the history of the user session"
Simplifying some jargons,
Cache is a overhead dynamic memory saved present along with the core storage which stores all relevant data frequently needed by the user.
Caching, is the practice by developers who assign certain parts of user data to be temporarily stored in the app or web session.
Expensive Calls, describe the heavy computation tasks to be done inside the app or third-party Network Calls which take time and are asynchronous in nature.
Now these calls, are most of the times "PURE" in nature, which means for a certain set input there will always be a set result and the result is invariable for the set of inputs given.
For Example,
const add =(a,b)=> a+b;
//add will always return same result for a set of any set of input.
Now if we want to create a memoization function for this add functionality, the code shall look somewhat like this to demonstrate the caching and implementing memoization.
import { StrictMode } from "react";
import ReactDOM from "react-dom";
import App from "./App";
const rootElement = document.getElementById("root");
ReactDOM.render(
<StrictMode>
<App />
</StrictMode>,
rootElement
);
const add=(a,b)=> a+b;
const memoize =(fn)=>{
let cache={}
return (...args)=>{
let cacheKey=args.map(n=>n.toString()+",").join("");
if (cacheKey in cache){
console.log("Fetched from Cache",cacheKey,cache[cacheKey]);
return cache [cacheKey];
}
else{
let res=args.reduce((acc,curr)=>fn(acc,curr),0)
cache[cacheKey]=res;
console.log("Expensive call",res);
return res;
}
}
}
const memoizeAdd=memoize(add)
console.log("result=",memoizeAdd(5,60,7));
console.log("result=",memoizeAdd(5,60,7));
//Output
//
//Expensive call 72
//result= 72
//Fetched from Cache 5,60,7 72
//result= 72
Code Walk Through
We initialize a "memoize" function which is a Higher order function and takes external functions as argument and maintains a separate memory (object in this case) to store memoized results from the past. We initialize "cache" object and we traverse through the input arguments and we further check if the same set of input has ever been provided and is present in cache. If so , we will directly fetch the value from cache bypassing the expensive external call to function ("add" in this case). If the set of input is not present in the arguments, we add the result from the call made with input as the object key for future use.
Thoughts?
It feels really empowered to have the technique of Memoization and caching which can be used handy whenever designing a JavaScript Application. We although also need to take care if the cache size does not grow too much and is rate limited & updated time-to-time to a certain affordable size according to the app requirement. A bigger cache can lead to performance limiting as it will be expensive to search through the larger stored cache.
I hope it was engaging and interesting to read about Memoization in this blog and you can now readily use it in your next upcoming JavaScript project to tweak you application performance. Thankyou, that's all folks!