Skip to content

手写实现一个缓存函数 memoize

Posted on:2024年8月22日 at 11:07

缓存函数(memoize)是一个优化技术,用于缓存函数的计算结果,以避免重复计算相同的输入。


下面是一个简单的手写 memoize 函数实现:

实现

function memoize(fn) {
  // 创建一个 Map 对象,用于存储缓存结果
  const cache = new Map();

  // 返回一个新的函数,这个函数会使用缓存
  return function (...args) {
    // 将参数转换为一个唯一的键
    const key = JSON.stringify(args);

    // 检查缓存中是否已有结果
    if (cache.has(key)) {
      return cache.get(key);
    }

    // 调用原始函数并存储结果
    const result = fn(...args);
    cache.set(key, result);

    return result;
  };
}

// 示例用法
function slowFunction(n) {
  // 模拟一个耗时操作
  for (let i = 0; i < 1e6; i++) {}
  return n * n;
}

// 创建一个缓存版本的 slowFunction
const memoizedSlowFunction = memoize(slowFunction);

console.time("First call");
console.log(memoizedSlowFunction(5)); // 输出: 25
console.timeEnd("First call"); // 第一次调用会比较慢

console.time("Second call");
console.log(memoizedSlowFunction(5)); // 输出: 25
console.timeEnd("Second call"); // 第二次调用会更快,因为结果被缓存了

说明

  1. memoize 函数

    • 接受一个函数 fn 作为参数。
    • 创建一个 Map 对象 cache 用于存储函数调用的结果,Map 是用于存储键值对的结构,支持按键访问。
    • 返回一个新函数,该函数首先检查缓存中是否存在对应参数的结果:
      • 如果存在,直接返回缓存中的结果。
      • 如果不存在,计算结果、缓存它,并返回结果。
  2. JSON.stringify(args)

    • 将函数参数转换为一个唯一的键,以便在 Map 中存储和检索结果。这种方式适用于简单参数(如基本数据类型和对象),但对于复杂对象(如函数、日期等),可能需要更复杂的键生成策略。
  3. 性能测试

    • 使用 console.timeconsole.timeEnd 测量函数调用的时间。第一次调用通常较慢,因为需要计算并缓存结果;第二次调用较快,因为结果已经在缓存中。

注意事项

扩展

可以根据实际需求对 memoize 函数进行扩展,例如添加缓存大小限制、定时缓存清理等。

原文转自:https://fe.ecool.fun/topic/112b5d92-47d7-40eb-9d8a-4321af6247bd