函数缓存Memoization

函数式编程风格中有一个“纯函数”的概念,纯函数是一种无副作用的函数,除此之外纯函数还有一个显著的特点:对于同样的输入参数,总是返回同样的结果。

性能提升

在平时的开发过程中,我们也应该尽量把无副作用的“纯计算”提取出来实现成“纯函数”,尤其是涉及到大量重复计算的过程,使用纯函数+函数缓存的方式能够大幅提高程序的执行效率。

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;
};