基础学习: memoize/memo

一个提升性能的函数
更新于: 2023-06-30 12:36:19

含义

记忆化函数(Memoization)的实现。记忆化是一种优化技术,用于存储函数的结果,以避免重复计算。

实现

  • 指定一个字符串类型的 key 用于 cache
  • 如果 key 不变,就直接返回结果
function memoize(fn) {
  const cache = {}; // 创建一个缓存对象,用于存储计算结果

  return function (arg) {
    if (cache.hasOwnProperty(arg)) {
      // 如果缓存中已经有这个参数的计算结果
      return cache[arg]; // 直接返回缓存的结果
    }

    const result = fn(arg); // 否则,调用原始函数进行计算
    cache[arg] = result; // 将计算结果存入缓存对象

    return result; // 返回计算结果
  };
}

改进

  • key 可以用函数来指定,理论上是任意类型
  • maxCacheSize: 指定上限,节省内存
function memoize(fn, keyGenerator = JSON.stringify) {
  const cache = {};

  return function (...args) {
    const key = keyGenerator(args);

    if (cache.hasOwnProperty(key)) {
      return cache[key];
    }

    const result = fn(...args);
    cache[key] = result;

    return result;
  };
}
function memoize(fn, keyGenerator = JSON.stringify, maxCacheSize) {
  const cache = {};
  const keys = [];

  return function (...args) {
    const key = keyGenerator(args);

    if (cache.hasOwnProperty(key)) {
      return cache[key];
    }

    const result = fn(...args);
    cache[key] = result;
    keys.push(key);

    if (maxCacheSize && keys.length > maxCacheSize) {
      const oldestKey = keys.shift();
      delete cache[oldestKey];
    }

    return result;
  };
}

cheatsheet

用法说明
缓存同步结果
// 示例用法:计算阶乘
const factorial = memoize(function (n) {
  if (n === 0 || n === 1) {
    return 1;
  }

  return n * factorial(n - 1);
});

console.log(factorial(5)); // 输出:120,计算了一次阶乘
console.log(factorial(5)); // 输出:120,直接从缓存中获取结果,无需再次计算
console.log(factorial(10)); // 输出:3628800,计算了一次阶乘
缓存异步结果
// 模拟一个异步的网络请求
const fetchData = memoize((url) => {
  return fetch(url)
    .then((response) => response.json())
    .then((data) => {
      return data;
    });
});

// 第一次请求数据
fetchData('https://api.github.com/users/afeiship').then((result) => {
  console.log(result);
});

// 第二次相同的请求,会从存储中获取结果,而不会真正发起网络请求
fetchData('https://api.github.com/users/afeiship').then((result) => {
  console.log(result);
});

实际应用

  • httpSchema 中的 cache 配置