函数缓存Memoization
2015 年 6 月 28 日
函数式编程风格中有一个“纯函数”的概念,纯函数是一种无副作用的函数,除此之外纯函数还有一个显著的特点:对于同样的输入参数,总是返回同样的结果。
性能提升
在平时的开发过程中,我们也应该尽量把无副作用的“纯计算”提取出来实现成“纯函数”,尤其是涉及到大量重复计算的过程,使用纯函数+函数缓存的方式能够大幅提高程序的执行效率。
Memoize
我们可以创建一个独立的函数来记忆任何函数。我们将此函数称为memoize。在传入相同的参数时直接返回上次缓存的结果,这样在计算大量有重复数据时,可以提供性能,
function memoize(func) { const cache = {}; return function(...args) { const key = JSON.stringify(args) if(!cache.hasOwnProperty(key)) { cache[key] = func.apply(this, args) } return cache[key] } } function sum(n1, n2) { const sum = n1 + n2 console.log(`${n1}+${n2}=${sum}`) return sum } const memoizedSum = memoize(sum) memoizedSum(1, 2) // 会打印出:1+2=3 memoizedSum(1, 2) // 没有输出
memoizedSum在第一次执行时将执行结果缓存在了闭包中的缓存对象cache中,因此第二次执行时,由于输入参数相同,直接返回了缓存的结果。
更好的选择是使用ES6+支持的Map对象
const memoize2 = fn => { const cache = new Map(); const cached = function(...val) { return cache.has(val) ? cache.get(val) : cache.set(val, fn.apply(this, val)) && cache.get(val); }; cached.cache = cache; return cached; };