Я нашел примеры, такие как факторный расчет, чтобы объяснить memoization . Они полезны, но я ищу более глубокое понимание.
Мне интересно, может ли кто-нибудь описать реальное приложение этого метода и почему он использовал его вместо рекурсии или что-то еще, что они чувствовали, используя memoization, может помочь им оптимизировать.
Запоминание немного более специфично, чем просто кеширование.
Подумайте о поиске элемента в DOM с помощью селектора, например, с помощью jQuery. Скажем, $('.some-selector')
. В этом контексте я вызываю функцию $
, говоря ей, чтобы найти для меня все элементы, которые имеют селектор CSS «.some-selector». Допустим, что документ большой, и мне нужно много раз вызывать $('.some-selector')
.
Вы можете сделать предположение, что каждый вызов $('.some-selector')
будет возвращать те же результаты, и поэтому выполнение фактической обработки каждый раз, когда он вызывается, – это потраченное впустую действие. Следовательно, $
может использовать аргумент ('.some-selector', в данном случае) в качестве ключа в некоторой таблице поиска или словаре. В первый раз, когда функция вызывается с этим аргументом, она обрабатывается нормально, результаты помещаются в словарь с использованием аргумента в качестве ключа, и результаты возвращаются. Последующие вызовы обнаруживают, что ключ имеет значение в словаре, представляющем результаты, которые уже были рассчитаны, поэтому он просто возвращает эти предыдущие результаты. Чистый эффект заключается в том, что вы не тратите время на поиск результатов, которые вы уже знаете.
Немного грубый пример JavaScript:
var _dictionary = {}; function $(selector) { if (_dictionary[selector]) return _dictionary[selector]; // lookup the results of the selector and return them if they exist // otherwise, execute the function's logic normally // TODO: search logic var results = doSearch(); _dictionary[selector] = results; return results; }
Эта ссылка идет более подробно и даже включает в себя общую функцию memoize
JS, которая может быть использована для любой другой функции.
Вы можете использовать memoization для всех видов кэширования. Например, вы можете кэшировать результаты некоторого вызова ajax.
Пример:
var cache = new Array() function memoized_ajax(url, callback) ( if (cache[url]) { callback(cache[url]); // we already know the result for this url } else { $.ajax({ url: url, success: function(data) { cache[url] = data; // we will remember result for this url callback(data); }); } }
Вы можете удалить это, если хотите, поскольку я не могу ответить на ваш вопрос (это дает вам пример использования memoization), но я хотел бы указать, что memoization предназначен для решения совершенно другого типа проблемы, чем рекурсия. Memoization сохраняет вывод вызова метода, так что получение результата будущих идентичных вызовов метода (те же параметры и привязки объектов) является поиском, а не вычислением. Рекурсия – это тип функционального алгоритма. Это означает, что они не противоречат, так как вы можете memoize выход рекурсивной функции.