浅谈js自记忆函数

时间: 2018-07-26阅读: 1796标签: js知识

最近阅读《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属性来确认是否已经有自记忆的缓存,如果没有,创建一个。

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

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

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


总结

自记忆函数有两个优点:

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

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

  • 任何类型的缓存都必然会为性能牺牲内存。
  • 很多人认为缓存逻辑不应该和业务逻辑混合,函数或方法只需要把一件事情做好。
  • 对自记忆函数很难做负载测试或估算算法复杂度,因为结果依赖于函数之前的输入。


来源:https://www.cnblogs.com/karthuslorin/archive/2018/07/25/9369066.html

站长推荐

1.云服务推荐: 国内主流云服务商,各类云产品的最新活动,优惠券领取。地址:阿里云腾讯云华为云

链接: http://www.fly63.com/article/detial/953

js的微任务和宏任务

宏任务:当前调用栈中执行的代码成为宏任务。微任务: 当前(此次事件循环中)宏任务执行完,在下一个宏任务开始之前需要执行的任务,可以理解为回调事件。

await在forEach不起作用解决

我们知道await这个机制肯定是没问题的,如果真的有问题肯定不会轮到我测出来,那么其实剩下来的问题只能是for遍历的原因了。lodash的forEach和[].forEach不支持await,如果非要一边遍历一边执行await,可使用for-of

js秒数转换成时分秒_js如何将秒拼接为时分秒显示?

接口返回的是int类型的秒数,在前端显示要求拼接为时分秒显示,这篇文章主要讲解实现js秒数转换成时分秒的方法。

js 实现栈和队列

js实现栈或者队列有两种方式: 1.数组:数组本身提供栈方法(push,pop),队列方法(push,shift)。 2.链表:构造链表结构,说白了就是链表的插入(尾插),移除(栈:末尾节点移除,队列:头结点移除)

JavaScript中的行为委托

行为委托简单来说就是一种设计模式,不同于传统的构造函数的类式设计。这里每个例子会通过构造函数,class和行为委托来不同实现,不过不会评论class,是否使用class取决于你的观点。

base91 for javascript

原理和 base64 是一样的,ASCII 共有94个可打印字符,base64 使用了其中 64 个,base91 使用了 91 个。

JavaScript 优雅的实现方式包含你可能不知道的知识点【转】

Js优雅的实现方式包含你可能不知道的知识点:简短优雅地实现 sleep 函数,js获取时间戳,js数组去重,js数字格式化,js交换两个整数,将 argruments 对象(类数组)转换成数组,数字取整等

7个常见的 JavaScript 测验及解答

我相信学习新事物并评估我们所知的东西对自己的进步非常有用,可以避免了我们觉得自己的知识过时的情况。在本文中,我将介绍一些常见的 JavaScript 知识。请享用!

Js中的命名空间(namespace)

全局变量应该由有系统范围相关性的对象们保留,并且它们的命名应该避免含糊并尽量减少命名冲突的风险。在实践中,这意味着你应该避免创建全局对象,除非它们是绝对必须的。 所以你对此是怎么做的?传统方法告诉我们,最好的消除全局策略是创建少数作为潜在模块和子系统的实际命名空间的全局对象。

JavaScript中的循环和作用域

JavaScript有一个特点,也许会让开发者头痛, 是与循环和作用域相关的.const。最简单的方案是用 let 声明、另外一个非常普遍的解决这个问题是使用pre-ES6代码, 同时它被称作即时调用函数表达式(IIFE)

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!