function memoize(fn) {
const cache = new Map();
return function (arg) {
if (!cache.has(arg)) cache.set(arg, fn.call(this, arg));
return cache.get(arg);
};
}
Memoization saves a function's results by its arguments. When you call it again with the same input, it returns the saved result instead of computing it again. It uses more memory to gain speed.
It is only safe for pure functions. A pure function's output depends only on its inputs.
A basic version: keep a Map in a closure. Check cache.has(key). If the key is missing, compute the result and store it.
Pitfalls:
- Choosing the key. A single primitive argument works directly. Many arguments are often joined with
JSON.stringify. This is slow, and it fails for functions, cyclic objects and objects with keys in a different order. - Object arguments are compared by reference, so two equal-looking objects are different keys.
- The cache grows forever. For long-lived functions with many inputs, this is a memory leak. Use an LRU limit (Least Recently Used: remove the oldest unused entries), or a
WeakMapfor object keys. - Async functions should cache the promise, not the final value. This stops duplicate requests while the first one is still running.
React's useMemo and React.memo are related ideas.
- Memoization saves results by their arguments and returns the saved value on repeat calls.
- Use it only for pure functions that always give the same output for the same input.
- Choosing the cache key is the hard part.
- Caches with no limit leak memory. Use an LRU limit or a
WeakMap. - React's
useMemoandReact.memoare related ideas.
Read more