← Назад к вопросам
В чем разница между функцией Мемоизированной и Обычной?
2.3 Middle🔥 161 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Разница между мемоизированной и обычной функцией
Мемоизация — это техника оптимизации, при которой результаты функции кэшируются (запоминаются) на основе входных аргументов. При повторном вызове с теми же аргументами функция возвращает закэшированный результат вместо повторного вычисления.
Обычная функция вычисляет результат каждый раз заново, независимо от входных данных.
Обычная функция
Вычисляет результат при каждом вызове:
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n - 1) + fibonacci(n - 2);
}
console.time("fib");
console.log(fibonacci(40)); // Очень медленно!
console.timeEnd("fib"); // ~500ms
Проблема: функция fibonacci(n) вызывается много раз с одинаковыми аргументами, что приводит к неэффективности.
Мемоизированная функция
Хранит результаты в кэше:
function memoize(fn) {
const cache = {};
return function(...args) {
const key = JSON.stringify(args);
if (key in cache) {
console.log("Из кэша:", key);
return cache[key];
}
const result = fn(...args);
cache[key] = result;
return result;
};
}
const memoizedFib = memoize(function fibonacci(n) {
if (n <= 1) return n;
return memoizedFib(n - 1) + memoizedFib(n - 2);
});
console.time("memoized");
console.log(memoizedFib(40)); // Почти мгновенно!
console.timeEnd("memoized"); // ~1ms
Сравнение производительности
| Аспект | Обычная функция | Мемоизированная функция |
|---|---|---|
| Первый вызов | Быстро | Немного медленнее |
| Повторный вызов (те же аргументы) | Полное вычисление | Мгновенно (из кэша) |
| Память | Минимум | Требует больше памяти |
| Применение | Простые функции | Дорогостоящие функции |
Примеры мемоизации в React
1. useMemo (для значений)
function UserProfile({ userId }) {
const userDetails = useMemo(() => {
console.log("Вычисляем подробные данные...");
return computeUserDetails(userId);
}, [userId]); // Пересчитывается только при изменении userId
return <div>{userDetails.name}</div>;
}
2. useCallback (для функций)
function Parent() {
const handleClick = useCallback(() => {
console.log("Клик");
}, []); // Функция не пересоздается при каждом рендере
return <Child onClick={handleClick} />;
}
3. memo (для компонентов)
const Button = React.memo(function Button({ label, onClick }) {
console.log("Рендер Button");
return <button onClick={onClick}>{label}</button>;
});
Ручная мемоизация с параметром
function memoizeWithLimit(fn, limit = 10) {
const cache = new Map();
return function(...args) {
const key = JSON.stringify(args);
if (cache.has(key)) {
return cache.get(key);
}
const result = fn(...args);
cache.set(key, result);
if (cache.size > limit) {
const firstKey = cache.keys().next().value;
cache.delete(firstKey);
}
return result;
};
}
Когда использовать мемоизацию
Используй мемоизацию когда:
- Функция вычисляет дорогостоящий результат (математические расчеты, обработка данных)
- Функция вызывается часто с одинаковыми аргументами
- Результат детерминирован (одинаковые входные данные = одинаковый выход)
Избегай мемоизации когда:
- Функция простая и быстрая
- Аргументы редко повторяются
- Функция имеет побочные эффекты (API запросы, изменение состояния)
Важные моменты
- Кэш растет: при неограниченном кэше возможна утечка памяти
- Ключ кэша:
JSON.stringify()может быть медленным для больших объектов - Чистота функции: мемоизация работает только для чистых функций
- React оптимизация:
useMemo,useCallback,memo— встроенные инструменты мемоизации - Профилирование: всегда проверяй, действительно ли мемоизация улучшает производительность