Can anyone give me an example of underscore.js _.memoize() in action?
Preferably using the hashFunction, and even more preferably in coffeescript?
Here is a slightly modified version of that cute change counting function from SICP in coffeescript:
countChange = (amount)->
cc = (amount, kindsOfCoins)->
firstDenomination = (kindsOfCoins)->
switch kindsOfCoins
when 1 then 1
when 2 then 5
when 3 then 10
when 4 then 25
if amount is 0 then 1
else if amount < 0 or kindsOfCoins is 0 then 0
else
(cc amount, (kindsOfCoins - 1)) +
(cc (amount - firstDenomination(kindsOfCoins)), kindsOfCoins)
cc amount*100, 4
console.log "Ways to make change for $0.85: " + countChange(.85)
How might I use underscore’s _.memoize() on that for example?
Many thanks in advance!
ps.. also, please don’t hesitate to shoot holes in the way that function was coded.. I’m very new to coffeescript and any help on making that code more idiomatic is welcome too.
One use of
memoizehere would be to reduce the number of calls to the innerccfunction:I’ve also rearranged things a little bit for compactness and I moved
firstDenominationoutside ofccto simplifyccwhile I was there; whether my firstDenominationis better than yours is a matter of taste, I have a bias against using aswitchto implement a simple lookup table but YMMV.The memoized version says “211 iterations of cc”, demo: http://jsfiddle.net/ambiguous/FZsJU/
A non-memoized version says “8141 iterations of cc”, demo: http://jsfiddle.net/ambiguous/Xn944/
So the non-memoized version calls
cc~40 times more often. The memoization may or may not be worthwhile depending on the computational overhead of the hashing function (mine is sufficient for demonstration purposes but not exactly optimized) and the overhead of the cache lookup. This is the standard question to ask when memoizing: is the caching faster than the cached computation?If we look at the implementation of
_.memoize:then you can see how it works and how the
hasheris used. Thememoobject is used as a cache, and thehasheris used to convert the arguments of the memoized function to a key inmemo; if we find the key then we can return the cached value immediately, otherwise we compute it the (presumably) slow way, cache it, and return it.