• 浅谈自记忆函数


    浅谈自记忆函数

    最近阅读《JavaScript忍者秘籍》看到了一种有趣的函数:自记忆函数。

    简介

    何为自记忆函数?书中提到:

    记忆化(memoization)是一种构建函数的处理过程,能够记住上次计算结果

    通过这句话可以得出,自记忆函数其实就是能够记住上次计算结果的函数。在实现中,我们可以这样进行处理:当函数计算得到结果时,就将该结果按照参数存储起来。采取这种方式时,如果另外一个调用也使用相同的参数,我们则可以直接返回上次存储的结果而不是再计算一遍。

    显而易见,像这样避免既重复又复杂的计算可以显著提高性能。对于动画中的计算、搜索不经常变化的数据或任何耗时的数学计算来说,记忆化这种方式是十分有用的。

    一个自记忆函数的例子

    下面这个例子展现自记忆函数的工作方式:

    // 自记忆素数检测函数
    function isPrime (value) {
      // 创建缓存
      if (!isPrime.answers) {
        isPrime.answers = {};
      }
      // 检查缓存的值
      if (isPrime.answers[value] !== undefined) {
        return isPrime.answers[value];
      }
      // 0和1不是素数
      var prime = value !== 0 && value !== 1;
      // 检查是否为素数
      for (var i = 2; i < value; i++) {
        if (value % i === 0) {
          prime = false;
          break;
        }
      }
      // 存储计算值
      return isPrime.answers[value] = prime
    }
    

    isPrime函数是一个自记忆素数检测函数,每当它被调用时:

    首先,检查它的answers属性来确认是否已经有自记忆的缓存,如果没有,创建一个。

    接下来,检查参数之前是否已经被缓存过,如果在缓存中找到该值,直接返回缓存的结果。

    如果参数是一个全新的值,进行正常的素数检测。

    最后,存储并返回计算值。

    总结

    自记忆函数有两个优点:

    • 由于函数调用时会寻找之前调用所得到的值,所以用户最终会乐于看到所获得的性能收益。
    • 它不需要执行任何特殊请求,也不需要做任何额外初始化,就能顺利进行工作。

    但是,自记忆函数并不是完美的,它一样有着缺陷:

    • 任何类型的缓存都必然会为性能牺牲内存。
    • 很多人认为缓存逻辑不应该和业务逻辑混合,函数或方法只需要把一件事情做好。
    • 对自记忆函数很难做负载测试或估算算法复杂度,因为结果依赖于函数之前的输入。
  • 相关阅读:
    测试常用的sql语句总结
    测试常用的Linux命令总结
    【转载】vim 中如何替换选中行或指定几行内的文本
    1074 Reversing Linked List
    1077 Kuchiguse
    LC 355. Design Twitter
    LCP 5. 发 LeetCoin
    LC 1409. Queries on a Permutation With Key
    1095 Cars on Campus
    LC 1369. Get the Second Most Recent Activity
  • 原文地址:https://www.cnblogs.com/karthuslorin/p/9369066.html
Copyright © 2020-2023  润新知