Memoize Function
Performance4 functions
Utility Overview
Details
Caches function results to avoid expensive recalculations, improving performance for pure functions with predictable inputs
Category:Performance
Functions:memoize, memoizeLRU, memoizeTTL, memoizeSimple
Performance:
- Time: O(1) for cache hits, O(f) for original function execution - Space: O(n) where n is number of unique input combinations cached
Concepts:
closurescachingperformance optimizationpure functions
Implementation
memoize
Time: O(1) | Space: O(n)
export function memoize<Args extends unknown[], Return>(
fn: (...args: Args) => Return,
keyGenerator?: (...args: Args) => string
): (...args: Args) => Return {
if (typeof fn !== 'function') throw new Error("First argument must be a function");
const cache = new Map<string, Return>();
const generateKey = keyGenerator || ((...args: Args) => JSON.stringify(args));
return (...args: Args): Return => {
const key = generateKey(...args);
if (cache.has(key)) {
return cache.get(key)!;
}
const result = fn(...args);
cache.set(key, result);
return result;
};
}
// Memoize with LRU cache to prevent memory leaksUsage Examples
Recursive function optimization
const fibonacci = (n: number): number => {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
};
const memoizedFib = memoize(fibonacci);
// Without memoization: ~1.5 seconds
// With memoization: ~1 millisecond
console.time('memoized');
memoizedFib(40); // 102334155
console.timeEnd('memoized');API response caching with TTL
const fetchUsers = async (endpoint: string) => {
const response = await fetch(`/api/${endpoint}`);
return response.json();
};
const cachedFetch = memoizeTTL(fetchUsers, 60000); // 1 minute cache
// First call: makes HTTP request
await cachedFetch('users');
// Subsequent calls within 1 minute: returns cached data
await cachedFetch('users'); // No HTTP request madeLRU cache for memory management
const processLargeDataset = (data: unknown[]) => {
// Expensive computation
return data.reduce((acc, item) =>
acc + complexCalculation(item), 0);
};
const memoizedProcess = memoizeLRU(processLargeDataset, 50);
// Only keeps 50 most recent results in memory
for (let i = 0; i < 100; i++) {
memoizedProcess(generateData(i));
}
// Memory usage stays constantSimple memoization for single arguments
const expensiveHash = (input: string) => {
// Simulate expensive hashing operation
let hash = 0;
for (let i = 0; i < input.length * 1000; i++) {
hash = ((hash << 5) - hash + input.charCodeAt(i % input.length)) & 0xffffffff;
}
return hash.toString(16);
};
const memoizedHash = memoizeSimple(expensiveHash);
// First call: performs expensive calculation
memoizedHash('password123'); // Takes time
// Subsequent calls: instant return
memoizedHash('password123'); // Instant