Що таке мемоізація?
1. Визначення
Мемоізація - це техніка оптимізації, при якій результати функції кешуються і при повторних викликах з тими самими аргументами беруться з пам'яті, а не обчислюються заново.
Тобто:
Якщо функція вже порахувала результат для цих вхідних даних - другого разу вона просто поверне збережене значення.
2. Приклад без мемоізації
function slowSquare(n) {
console.log('Обчислюю...');
return n * n;
}
console.log(slowSquare(4)); // "Обчислюю..." -> 16
console.log(slowSquare(4)); // "Обчислюю..." знову -> 16Проблема: кожен виклик заново рахує результат, навіть якщо аргумент той самий.
3. Приклад з мемоізацією
function memoizedSquare() {
const cache = {};
return function (n) {
if (n in cache) {
console.log('Беремо з кешу');
return cache[n];
}
console.log('Обчислюю...');
const result = n * n;
cache[n] = result;
return result;
};
}
const square = memoizedSquare();
console.log(square(4)); // "Обчислюю..." -> 16
console.log(square(4)); // "Беремо з кешу" -> 16Тепер функція рахує тільки один раз, а потім віддає значення з кешу.
4. Коли мемоізація корисна
- Функція чиста (pure) - залежить тільки від вхідних аргументів і не має побічних ефектів;
- Функція виконує дорогі обчислення (наприклад, сортування, рекурсія, фільтрація, рендеринг);
- Функція викликається часто з тими самими аргументами.
5. Класичні приклади
Приклад - рекурсивний fibonacci
Без мемоізації:
function fib(n) {
if (n <= 1) return n;
return fib(n - 1) + fib(n - 2);
}
console.log(fib(40)); // Дуже довго!З мемоізацією:
function memoFib() {
const cache = {};
return function f(n) {
if (n in cache) return cache[n];
if (n <= 1) return n;
cache[n] = f(n - 1) + f(n - 2);
return cache[n];
};
}
const fib = memoFib();
console.log(fib(40)); // Майже миттєвоРізниця величезна: час падає з O(2ⁿ) до O(n).
6. Мемоізація в React
У React мемоізація використовується для запобігання зайвим ререндерам.
| Хук | Що робить | Приклад |
|---|---|---|
useMemo | Мемоізує результат обчислення | const value = useMemo(() => expensiveCalc(data), [data]) |
useCallback | Мемоізує функцію (щоб не пересоздавалася на кожен рендер) | const handleClick = useCallback(() => {...}, [deps]) |
React.memo | Мемоізує компонент (не ререндерить, якщо пропси не змінилися) | export default React.memo(MyComponent) |
Це те саме, що й у звичайному JS, тільки на рівні React-компонентів.
7. Популярні бібліотеки
-
lodash.memoize- готова реалізація:javascriptimport memoize from 'lodash.memoize'; const square = memoize(x => x * x); console.log(square(5)); // обчислить console.log(square(5)); // з кешу -
memoizee- просунутий кеш з TTL, max size тощо.
8. Коли мемоізацію не варто використовувати
- Функція майже миттєва (дешеві обчислення);
- Аргументи щоразу різні (немає сенсу кешувати);
- Пам'ять обмежена (занадто великий кеш може "з'їсти" RAM);
- У функції є побічні ефекти (HTTP-запит, зміна зовнішніх даних).
Короткий підсумок
| Що це | Навіщо | Коли використовувати |
|---|---|---|
| Кешування результатів функції | Прискорює повторні обчислення | При частих викликах з тими самими аргументами |
| Працює для "чистих" функцій | Без побічних ефектів | Коли обчислення дорогі |
| Не підходить для непередбачуваних вхідних даних | Немає повторів - немає користі | - |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.