DEV Community

Cover image for Memoization in JS
Damian Cipolat
Damian Cipolat

Posted on • Edited on

Memoization in JS

Memoization

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.

Memoizing

Memoizing in simple terms means memorizing or storing in memory. A memoized function is usually faster because if the function is called subsequently with the previous value(s), then instead of executing the function, we would be fetching the result from the cache.

Pure funtions

A function is a process which takes some input, called arguments, and produces some output called a return value.

Is same as caching?

Yes, Memoization is actually a specific type of caching. While caching can refer in general to any storing technique (like HTTP caching) for future use, memoizing specifically involves caching the return values of a function.

When to memoize your functions?

  • Only pure functions.
  • Api calls.
  • Heavy computational functions.

Memoize js code:

This memoize store the functions arguments in a internal cache, using bas64 to encode the parameters to create a hash. We are following the principle, that f(a) = b and alway when function is calle with a returns b.

//Memoize function: high order, curryng.
const memoize = (fn) => {

  let cache = {};

  return (...args) => {

    //Create hash.
    const n = btoa(args);

    //Find in cache or store new values.
    if (n in cache)      
      return cache[n];
    else {    
      let result = fn(n);
      cache[n] = result;

      return result;
    }

  }

}

//Function to be stored.
const sum = (x,y) =>x+y;

//Wrapp a function.
const memoizeSum = memoize(add);

//Tests
console.log(memoizeSum(3,1));  // calculated
console.log(memoizeSum(3,1));  // cached
console.log(memoizeSum(4,4));  // calculated
console.log(memoizeSum(4,4));  // cached
Enter fullscreen mode Exit fullscreen mode

Memoize js + timeout:

The same memoize function, but using a timeout to expire the cache after the time finish.

const memoizeTimeout = (fn,time) => {

  let cache = {};
  let timeId;

  return (...args) => {

      //Erase cache.
      timeId = setTimeOut(()=>{
        cache={};
        clearInterval(timeId);
      });

      //Create hash.
      const n = btoa(args);

      //Find in cache or store new values.      
      if (n in cache){        
        return cache[n];
      } else {    
        let result = fn(n);        
        cache[n] = result;

        return result;
      }

    },time);    

  }

}

//Function to be stored.
const sum = (x,y) =>x+y;

//Wrapp a function.
const memoizeSum = memoizeTimeout(sum,1000);

//Tests
console.log(memoizeSum(3,1));  // calculated
console.log(memoizeSum(3,1));  // cached
console.log(memoizeSum(4,4));  // calculated
console.log(memoizeSum(4,4));  // cached
Enter fullscreen mode Exit fullscreen mode

Resources:

Writted with 💖

Top comments (8)

Collapse
 
marcelobarrera profile image
Marcelo

Hi Damian, interesting but when I take the code to any editor, the code does not seem to work, I just tried on "code sand box" for example and did not work. Maybe you would like to check it out again? Thank you.

Collapse
 
fullzero5 profile image
FullZero

a typo in the text uses the wrong function
is described sum add is called

Collapse
 
damxipo profile image
Damian Cipolat

Fixed!

Collapse
 
fullzero5 profile image
FullZero

thank you very much for the useful content

Collapse
 
damxipo profile image
Damian Cipolat

Thanks

Collapse
 
superyarik profile image
superyarik

hi, looks like string
},time);
not in it place

Collapse
 
superyarik profile image
superyarik • Edited

i've fix your last example with time

const memoizeTimeout = (fn,time) => {

  let cache = {};

  return (...args) => {

      //Create hash.
      const n = btoa(args);

      //Erase cache.
      setTimeout(()=>{
        if (n in cache){    
          delete cache[n];
        }
      },time);

      //Find in cache or store new values.      
      if (n in cache){        
        return cache[n];
      } else {    
        let result = fn(...args);        
        cache[n] = result;

        return result;
      }

  }

}
Enter fullscreen mode Exit fullscreen mode

no need to clearInterval - couse it clean setInterval after first run and not work correct for many launches with different params

Collapse
 
veritasv profile image
Andrey Zdrobilko

Hi Damian, pls fix the typo with the function name also in the first example.
And why you call the function with hashed arguments?

let result = fn(n) vs let result = fn(...args)