Skip to content

Instantly share code, notes, and snippets.

@rolandcoops
Last active October 30, 2019 06:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rolandcoops/5b7894d1e9168a93bd674d73bae39014 to your computer and use it in GitHub Desktop.
Save rolandcoops/5b7894d1e9168a93bd674d73bae39014 to your computer and use it in GitHub Desktop.
Small tree-based memoization module that handles any number of arguments (by reference). Slower than _.memoize (especially for multiple args), but with the advantage of computing keys based on all function arguments, not just the first.
const value = Symbol('value')
const retrieve = (node, path) => {
for (let i = 0; i < path.length; i++) {
const key = path[i]
if (node.has(key)) {
node = node.get(key)
} else {
const child = new Map()
node.set(key, child)
node = child
}
}
return node
}
const memoize = (fn) => {
let cache = new Map()
let size = 0
function memoized (...args) {
const node = retrieve(cache, args)
// if key is in cache, return cached previous result
if (node.has(value)) return node.get(value)
// otherwise perform expensive function, cache result and return
const result = fn.apply(this, args)
node.set(value, result)
return result
}
// expose cache (e.g. to allow manual clearing)
Object.defineProperty(memoized, "cache", {
get: () => cache,
})
return memoized
}
export default memoize
@rolandcoops
Copy link
Author

rolandcoops commented Oct 30, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment