WikiSort.ru - Программирование

ПОИСК ПО САЙТУ | о проекте

Мемоизация (запоминание, от англ. memoization (англ.) в программировании) — сохранение результатов выполнения функций для предотвращения повторных вычислений. Это один из способов оптимизации, применяемый для увеличения скорости выполнения компьютерных программ. Перед вызовом функции проверяется, вызывалась ли функция ранее:

  • если не вызывалась, функция вызывается и результат её выполнения сохраняется;
  • если вызывалась, используется сохранённый результат.

Мемоизация может использоваться не только для увеличения скорости работы программы. Например, она используется при простом взаимно-рекурсивном нисходящем синтаксическом разборе в обобщённом алгоритме нисходящего синтаксического анализа[1].

Несмотря на связь с кешированием, мемоизация является особым видом оптимизации, отличающимся от таких способов кеширования, как буферизация и подмена страниц.

В рамках языков логического программирования мемоизация известна под названием «табулирования».

Примеры использования

Приведенная ниже функция memoize() сохраняет результаты каждого вызова принимаемой функции в виде [ключ:значение].

// Функция, генерирующая ключ исходя из параметров
const generateKey = args => ( 
  args.map(x => x.toString() + 	':' + typeof(x)).join('|') // Результат: [x1:number|x2:number]
);

// Принимает функцию в качестве параметра
const memoize = fn => {
  const cache = {};
  return (...args) => { 
// Генерирует ключ для сохранения результата
    const key = generateKey(args); 
    const val = cache[key];
// Проверяет, существует по данному ключу какое-либо значение и возвращает его, если оно есть
    if (val) return val;
// Сохраняет результат вызова функции
    const res = fn(...args);
    cache[key] = res;
// Возвращает результат
    return res; 
  };
};

С помощью нее мы можем избежать повторного выполнения вычислений в случае, если они уже были произведены.

// Функция, находящая сумму чисел от a до b
const sumSeq = (a, b) => {
  console.log('Calculate sum');
  let r = 0;
  for (let i = a; i < b; i++) r += i;
  return r;
}; 

// Производим мемоизацию функции sumSeq
const mSumSeq = memoize(sumSeq);

console.log('First call mSumSeq(2, 5)');
console.log('Value: ' + mSumSeq(2, 5)); // Выводит  в консоль "9"
console.log('Second call mSumSeq(2, 5)');
console.log('From cache: ' + mSumSeq(2, 5)); // Выводит в консоль "9"
console.log('Call mSumSeq(2, 6)');
console.log('Calculated: ' + mSumSeq(2, 6)); // Выводит в консоль "14"

При повторном вызове функции mSumSeq( 2, 5 ) программа не выполняла повторные вычисления суммы, она проверила наличие значения по ключу [2:number|5:number] в кеше, и, поскольку он уже был создан и ему было присвоено значение 9 при первом вызове функции, это значение передастся переменной val из memoize() и возвратится в качестве аргумента в console.log().

Данный пример показывает самое простое применение мемоизации в программировании, поэтому особых изменений в скорости работы можно не заметить, однако этот способ оптимизации может сильно облегчить работу процессора при нагруженных математических вычислениях.

См. также

Ссылки

Примеры кода взяты из источника:

HowProgrammingWorks, Тимур Шемсединов - Github репозиторий.

Примечания

  1. Norvig, Peter. Techniques for Automatic Memoization with Applications to Context-Free Parsing // Computational Linguistics. — 1991. Т. 17, № 1. С. 91–98.

Данная страница на сайте WikiSort.ru содержит текст со страницы сайта "Википедия".

Если Вы хотите её отредактировать, то можете сделать это на странице редактирования в Википедии.

Если сделанные Вами правки не будут кем-нибудь удалены, то через несколько дней они появятся на сайте WikiSort.ru .




Текст в блоке "Читать" взят с сайта "Википедия" и доступен по лицензии Creative Commons Attribution-ShareAlike; в отдельных случаях могут действовать дополнительные условия.

Другой контент может иметь иную лицензию. Перед использованием материалов сайта WikiSort.ru внимательно изучите правила лицензирования конкретных элементов наполнения сайта.

2019-2024
WikiSort.ru - проект по пересортировке и дополнению контента Википедии