Added lume.memoize(), updated README.md and tests

This commit is contained in:
rxi 2014-05-01 18:58:29 +01:00
parent 6a160a3afe
commit 0716caf6a1
3 changed files with 40 additions and 0 deletions

View File

@ -208,6 +208,14 @@ f() -- Prints "Hello"
f() -- Does nothing f() -- Does nothing
``` ```
### lume.memoize(fn)
Returns a wrapper function to `fn` where the results for any given set of
arguments are cached. `lume.memoize()` is useful when used on functions with
slow-running computations.
```lua
fib = lume.memoize(function(n) return n < 2 and n or fib(n-1) + fib(n-2) end)
```
### lume.time(fn, ...) ### lume.time(fn, ...)
Inserts the arguments into function `fn` and calls it. Returns the time in Inserts the arguments into function `fn` and calls it. Returns the time in
seconds the function `fn` took to execute followed by `fn`'s returned values. seconds the function `fn` took to execute followed by `fn`'s returned values.

View File

@ -269,6 +269,24 @@ function lume.once(fn, ...)
end end
local memoize_fnkey = {}
local memoize_nilkey = {}
function lume.memoize(fn)
local cache = {}
return function(...)
local c = cache
for i = 1, select("#", ...) do
local a = select(i, ...) or memoize_nilkey
c[a] = c[a] or {}
c = c[a]
end
c[memoize_fnkey] = c[memoize_fnkey] or {fn(...)}
return unpack(c[memoize_fnkey])
end
end
function lume.time(fn, ...) function lume.time(fn, ...)
local start = os.clock() local start = os.clock()
local rtn = {fn(...)} local rtn = {fn(...)}

View File

@ -279,6 +279,20 @@ tests["lume.once"] = function()
tester.test.error( lume.once, 123 ) tester.test.error( lume.once, 123 )
end end
-- lume.memoize
tests["lume.memoize"] = function()
local f = lume.memoize(
function(a, b, c)
return tostring(a) .. tostring(b) .. tostring(c)
end)
testeq( f("hello", nil, 15), "hellonil15" )
testeq( f("hello", nil, 15), "hellonil15" )
testeq( f(), "nilnilnil" )
testeq( f(), "nilnilnil" )
local f2 = lume.memoize(function() end)
testeq( f2(), nil )
end
-- lume.time -- lume.time
tests["lume.time"] = function() tests["lume.time"] = function()
local t, a, b, c = lume.time(function(x) return 50, 60, x end, 70) local t, a, b, c = lume.time(function(x) return 50, 60, x end, 70)