← Назад к вопросам

В чем разница между функцией Мемоизированной и Обычной?

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 — встроенные инструменты мемоизации
  • Профилирование: всегда проверяй, действительно ли мемоизация улучшает производительность