PROGRAMMING-CONCEPTS

Memoization: Definition, Purpose, and Examples

Memoization is an optimization technique where a function stores the results of expensive calculations and returns the cached value when the same inputs appear again. It improves performance by avoiding repeated work, especially in tasks involving recursion, data processing, or slow operations like API calls.

Memoization works best with pure functions—functions whose outputs depend only on inputs and have no side effects—because their results are predictable and safe to reuse.


How Memoization Works

The key idea is simple:

  1. Check if the function has seen the input before.
  2. If yes, return the stored result.
  3. If no, compute the result, store it, and return it.

This pattern reduces time complexity dramatically in some situations, especially recursive algorithms.


A Basic JavaScript Memoization Pattern

function memoize(fn) {
  const cache = {};

  return function (input) {
    if (cache[input] !== undefined) {
      return cache[input];
    }
    const result = fn(input);
    cache[input] = result;
    return result;
  };
}

This wrapper stores results inside cache, keyed by input. The next time the function is called with the same input, it returns the cached result instantly.

const square = memoize(n => n * n);
square(10); // computes
square(10); // retrieves from cache

The first call performs the multiplication, while the second is nearly instantaneous. This is a common pattern for performance-sensitive code.


React Example: useMemo

React doesn’t memoize functions automatically, but it offers useMemo() to memoize computed values inside components.

const total = useMemo(() => {
  return items.reduce((sum, item) => sum + item.price, 0);
}, [items]);

React only recalculates the total when items changes. This avoids unnecessary computations during re-renders, which improves UI performance when lists grow large.


TypeScript Example (Typed Memoization)

function memoizeNumber(fn: (n: number) => number) {
  const cache: Record<number, number> = {};

  return (n: number): number => {
    if (n in cache) return cache[n];
    return (cache[n] = fn(n));
  };
}

TypeScript ensures the memoized function only accepts and returns specific types. This adds safety but follows the same logic as JavaScript.


Python Example

Python developers often use dictionaries to implement memoization.

def memoize(fn):
    cache = {}

    def wrapper(n):
        if n in cache:
            return cache[n]
        result = fn(n)
        cache[n] = result
        return result

    return wrapper

This function decorates another function to add caching. It’s a straightforward pattern used frequently in recursive algorithms.

Using It on a Function

@memoize
def double(n):
    return n * 2

The function now keeps track of previous inputs and instantly returns cached values on repeat calls. This improves performance without needing to rewrite the original logic.


Swift Example Using a Dictionary

Swift doesn’t include built-in memoization, but you can implement it manually.

func memoize<T: Hashable, U>(_ fn: @escaping (T) -> U) -> (T) -> U {
    var cache: [T: U] = [:]

    return { input in
        if let value = cache[input] { return value }
        let result = fn(input)
        cache[input] = result
        return result
    }
}

Swift’s generics make this reusable for many types as long as the input is hashable. This lets you memoize computationally heavy functions in a clean and reusable way.


Memoization in Recursion

Memoization is especially powerful in recursive functions with overlapping subproblems, where the same values get recalculated repeatedly.

Fibonacci Without Memoization (Slow)

function fib(n) {
  if (n <= 1) return n;
  return fib(n - 1) + fib(n - 2);
}

This version recalculates the same Fibonacci values many times. Performance drops dramatically as n increases.

Fibonacci With Memoization (Fast)

const fibMemo = memoize(function fib(n) {
  if (n <= 1) return n;
  return fib(n - 1) + fib(n - 2);
});

The memoized version stores results for each n, turning exponential time into linear. This pattern is common in dynamic programming.


When Memoization Helps

Memoization becomes valuable when:

  • the function does expensive calculation
  • the same inputs occur repeatedly
  • the function is pure (consistent input → consistent output)
  • the cost of computing is higher than the cost of storing results

It’s especially common in:

  • recursive algorithms
  • data processing that revisits values
  • UI frameworks (React, SwiftUI) to prevent unnecessary rework
  • API logic to avoid duplicate calls

Memoization vs Caching

Memoization is a form of caching, but focused exclusively on function results.

General-purpose caching may store:

  • API responses
  • database queries
  • file contents
  • computed assets

Memoization specifically attaches the cache to a function.


Common Mistakes

Memoizing functions with side effects

If a function changes behavior over time or touches external state, memoizing it will return outdated or incorrect results.

Using objects as keys unintentionally

In JavaScript, {} !== {}, so using object inputs requires custom hashing logic.

Forgetting cache invalidation

Long-running programs may need strategies to clear old results.

Overusing memoization

Not every function benefits — sometimes the overhead outweighs the speedup.


Summary

Memoization stores the results of expensive function calls so they can be reused instantly when the same inputs appear. JavaScript and TypeScript often use higher-order functions, Python relies on dictionaries and decorators, and React offers useMemo for component performance. Applied correctly, memoization reduces repetitive computation, speeds up recursive algorithms, and helps maintain smooth UI performance.

Learn to Code for Free
Start learning now
button icon
To advance beyond this tutorial and learn to code by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

Reach your coding goals faster