Една употреба на memoize
тук би била да се намали броят на извикванията на вътрешната функция cc
:
n = 0
countChange = (amount)->
firstDenomination = (kindsOfCoins) ->
[1, 5, 10, 25][kindsOfCoins - 1]
cc = (amount, kindsOfCoins)->
++n # This is just a simple counter for demonstration purposes
return 1 if amount is 0
return 0 if amount < 0 or kindsOfCoins is 0
(cc amount, (kindsOfCoins - 1)) +
(cc (amount - firstDenomination(kindsOfCoins)), kindsOfCoins)
cc = _.memoize cc, (a,k) -> "#{a},#{k}"
cc amount*100, 4
console.log "Ways to make change for $0.85: #{countChange(.85)}"
console.log "#{n} iterations of cc"
Също така пренаредих малко нещата за компактност и преместих firstDenomination
извън cc
, за да опростя cc
, докато бях там; дали моят firstDenomination
е по-добър от вашия е въпрос на вкус, имам пристрастия срещу използването на switch
за внедряване на проста справочна таблица, но YMMV.
Мемоизираната версия казва „211 итерации на cc“, демонстрация: http://jsfiddle.net/ambiguous/FZsJU/
Немемоизирана версия казва „8141 итерации на cc“, демонстрация: http://jsfiddle.net/ambiguous/Xn944/
Така че немемоизираната версия извиква cc
~40 пъти по-често. Запаметяването може или не може да си струва в зависимост от изчислителните разходи на функцията за хеширане (моята е достатъчна за демонстрационни цели, но не е точно оптимизирана) и разходите за търсене в кеша. Това е стандартният въпрос, който трябва да зададете при мемоизиране: кеширането по-бързо ли е от кешираните изчисления?
Ако разгледаме внедряването на _.memoize
:
// Memoize an expensive function by storing its results.
_.memoize = function(func, hasher) {
var memo = {};
hasher || (hasher = _.identity);
return function() {
var key = hasher.apply(this, arguments);
return _.has(memo, key) ? memo[key] : (memo[key] = func.apply(this, arguments));
};
};
тогава можете да видите как работи и как се използва hasher
. Обектът memo
се използва като кеш, а hasher
се използва за преобразуване на аргументите на мемоизираната функция в ключ в memo
; ако намерим ключа, можем да върнем кешираната стойност веднага, в противен случай я изчисляваме по (вероятно) бавен начин, кешираме я и я връщаме.
person
mu is too short
schedule
16.04.2012