Logo

dev-resources.site

for different kinds of informations.

Memoization in JavaScript

Published at
4/24/2024
Categories
javascript
closures
memoization
Author
diegolepore
Categories
3 categories in total
javascript
open
closures
open
memoization
open
Author
11 person written this
diegolepore
open
Memoization in JavaScript

Following my previous post about closures in JavaScript, I wanted to continue the conversation and talk about memoization, which is a performance optimization technique that leverages closures.

Memoization relies on function purity. Pure functions consistently return the same output for identical input arguments. Memoization enhances efficiency by caching these arguments along with the output they generate. When these arguments are passed again, the function retrieves the result from the cache instead of recalculating it. This is basically why memoization is ideal only on pure functions, but this will be clearer as I illustrate the concept in the following example.

Consider a basic function to calculate the sum of numbers:

function sumNums(...nums) {
  return nums.reduce((total, num) => total + num, 0);
}

console.log(sumNums(1, 2, 3)); // Output: 6
Enter fullscreen mode Exit fullscreen mode

Now, imagine that instead of a straightforward operation like summing three numbers, we're dealing with a more complex function that uses recursion and challenging computations. In such cases, memoization is particularly valuable.

In our example, memoization optimizes the function by ensuring that the arithmetic operation is performed just once. This is achieved by storing 1, 2, 3 as the key and 6 as the value in an object that acts as the functionโ€™s cache. In my demonstration, I'll use an object for the cache, but you can choose any data structure that best suits your specific needs and preferences.

Let's define a memo function that takes another function and memoizes it, and then let's memoize our sumNums function:

/**
 * Memoizes a function to cache its results based on the arguments provided.
 * If the result for a given set of arguments is already in the cache, it retrieves it from there.
 * Otherwise, it calculates the result, stores it in the cache, and returns it.
 *
 * @param {Function} fn - The function to be memoize.
 * @returns {Function} The memoize function.
 */
function memo(fn) {
  const cache = {};

  return (...args) => {
    // Generate a unique key based on arguments to store function results
    const key = JSON.stringify(args);

    // Check if the result is already cached
    if (cache[key]) {
      return cache[key];
    }

    // Calculate the result and cache it if it's not already cached
    const result = fn(...args);
    cache[key] = result;
    return result;
  };
}

// Create a memoize version of the sumNums function
const memoizedSumNums = memo(sumNums);

console.log(memoizedSumNums(1, 2, 3)); 
// Calculates and returns 6

console.log(memoizedSumNums(1, 2, 3)); 
// Fetches and returns 6 from cache without recalculating

Enter fullscreen mode Exit fullscreen mode

I encourage you to try it out by memoizing different functions. For instance, you could try memoizing a fibbonacci function. And then you can compare how fast it runs with and without memoizing it.

To wrap up, memoization is a powerful technique for boosting the efficiency of pure functions by avoiding unnecessary recalculations, and enhancing performance. However, while memoization can significantly cut down on processing time, especially in scenarios involving complex tasks, it does so at the cost of increased memory usage.

As results are cached, memory consumption can grow, depending on the number and size of the cached results. This trade-off needs careful consideration, particularly in environments where memory is limited.

Opt for memoization when the benefits of reduced computation outweigh the costs of additional memory usage. This way, your functions not only run faster but also remain efficient in their use of system resources, keeping your code optimized and maintainable.

closures Article's
30 articles in total
Favicon
Understanding Closures in PHP: Key Differences and Use Cases
Favicon
JavaScript Closures in Depth: Unlocking the Power of Lexical Scope
Favicon
Understanding Closures in JavaScript
Favicon
Mastering Closures and Decorators in Python: From Basics to Advanced
Favicon
Understanding Closure in JavaScript.
Favicon
Let's Understand JavaScript Closures: A Fundamental Concept
Favicon
Memoization in JavaScript
Favicon
Closures: Performance implications
Favicon
Closures: Lifting the hood
Favicon
A Practical Introduction to Closures in JavaScript
Favicon
Unlocking New Possibilities: Rust Compiler Backend Brings Closures to the .NET Universe!
Favicon
๐Ÿ“ฆ๐Ÿ”“Closures in JavaScript visualized
Favicon
useClosure() {work, backwards in returnValuesAsInput (backwards, work)}
Favicon
Mastering Closures in JavaScript: A Comprehensive Guide
Favicon
# "JavaScript Closures: Demystified."
Favicon
Closures - JavaScript
Favicon
Exploring Advanced JavaScript Techniques: Closures, Prototypes, and Hoisting
Favicon
Unlocking JavaScript Magic: A Beginner's Guide to Closures
Favicon
JavaScript Closures: Understanding the Power of Functions
Favicon
Closures in javascript
Favicon
JavaScript Closure
Favicon
Groovy Gotchas - Loops, Closures, Scope, and Jenkins DSLs
Favicon
Understanding closures in JavaScript
Favicon
Javascript Currying and partials
Favicon
The ultimate explanation of closures
Favicon
Understanding Closures in JavaScript
Favicon
Closures and Memoization
Favicon
A Simple Explanation of JavaScript "Closures"
Favicon
Hoisting with closures example
Favicon
Closures in JavaScript

Featured ones: