#javascript
В книге Девида Фленегана в главе 8.8.4 Мемоизация есть пример кода и комментарий, на самом комментарии хотел бы остановиться ибо я не понял что автор имел ввиду. Для начала я вставлю код чтобы была понятна суть: // Возвращает мемоизованную версию функции f. Работает, только если все возможные // аргументы f имеют отличающиеся строковые представления. function memoize(f) { var cache = {}; // Кэш значений сохраняется в замыкании. return function() { // Создать строковую версию массива arguments для использования // в качестве ключа кэша. var key = arguments.length + Array.prototype.join.call(arguments,","); if (key in cache) return cache[key]; else return cache[key] = f.apply(this, arguments); }; } // Возвращает наибольший общий делитель двух целых чисел, используя // алгоритм Эвклида: http://en.wikipedia.org/wiki/Euclidean_algorithm function gcd(a,b) { // Проверка типов a и b опущена var t; // Временная переменная для обмена if (a < b) t=b, b=a, a=t; // Убедиться, что a >= b while(b != 0) t=b, b = a%b, a=t; // Это алгоритм Эвклида поиска НОД return a; } var gcdmemo = memoize(gcd); gcdmemo(85, 187) // => 17 // Обратите внимание, что при мемоизации рекурсивных функций желательно, // чтобы рекурсия выполнялась в мемоизованной версии, а не в оригинале. var factorial = memoize(function(n) { return (n <= 1) ? 1 : n * factorial(n-1); }); factorial(5) // => 120. Также поместит в кэш факториалы для чисел 4, 3, 2 и 1. А теперь не понятный мне комментарий: Обратите внимание, что при мемоизации рекурсивных функций желательно, чтобы рекурсия выполнялась в мемоизованной версии, а не в оригинале. Что значит выполнение рекурсии в мемоизованной версии? И чем отличается от оригинала? Возможный вариант понимания: 1. Функция выполняется внутри функции (мемоизованный вариант): Каждая итерация сохраняется в объекте 2. Функция выполняется внутри функции («не мемоизованный вариант»): Сохраняется последний результат вызова P.S Пишите что думаете по данному поводу.
Ответы
Ответ 1
В исходном тексте написано более понятно. Не очень понятно почему переводчик перевёл это так, но понятно что хотел сказать автор: если у вас есть какая-то рекурсивная функция, то для эффективной мемоизации нужно рекурсивно вызывать не саму функцию, а её мемоизированный вариант. var factorial = memoize(function(n) { return (n <= 1) ? 1 : n * factorial(n-1); }); factorial(5); // => 120. factorial(4); // посчитается мгновенно так как в кеше уже есть факториал для 4 factorial(6); // посчитается в одну операцию умножения // так как в кеше уже есть факториал для 5 factorial(100); // считаться будет почти полностью factorial(99); // посчитается мгновенно - результат есть в кеше
Комментариев нет:
Отправить комментарий