美文网首页
js性能优化-利用备忘模式进行结果缓存

js性能优化-利用备忘模式进行结果缓存

作者: 0月 | 来源:发表于2019-12-28 15:39 被阅读0次

计算优化

对于不变的结果能缓存就尽量缓存,这样子就减少每次使用的时候进行多次计算,浪费性能。
如:

  • 同步结果:
    利用 备忘模式 创建一个备忘函数 memorize;
    将同步执行的函数fn进行备忘,这个函数fn的计算结果就会缓存起来,当你传入相同的参数的时候就会直接返回缓存的结果
function memorize (fn) {
  const cache = {}
  return function(){
    const args = [].slice.call(arguments)
    const key = JSON.stringify(args)
    return cache[key] || (cache[key] = fn.apply(fn, args))
  }
}

const add = (x, y) => x + y

const addFn = memorize(add)

const res = addFn(1,2) // 3, 第一次执行add方法得结果
const res = addFn(1,2) // 3 ,第二次从cache中拿结果

上面的addFn 就是经过备忘的函数,里面利用闭包将计算结果缓存起来,再次传入相同的参数调用时就会从cache中拿结果而不是再次计算。这样子的好处就是对于多次计算复杂的过程有很明显性能提升,缺点也很明显:参数一变,内存消耗就会增大,因为key是由参数决定的。这也是闭包的注意点,消耗内存不释放,那这里是否可以优化?当然可以,可以定义cache的一个最大上限,然后当存满时可用算法FIFO 或者 LRU释放。其实vue源码中也有用到这么一个函数,思想大体上一致,在vue/src/shared/util.js中


cached.png
  • 异步结果
    对于异步结果就不能直接用memorize函数进行备忘了,但是也可以变通改造一下
// 异步函数的备忘函数
function AsyncMemorize (AsyncFn) {
  const cache = {}
  return function(){
    const args = [].slice.call(arguments)
    const key = JSON.stringify(args)
    return new Promise (function (resolve, reject) {
      if (cache.hasOwnProperty(key)){
        resolve(cache[key])
        return
      }
      AsyncFn.apply(AsyncFn, args).then(res => {
        cache[key] = res
        resolve(res)
     }).catch(e => reject(e))
    })
  }
}

实验一下,假如有个异步函数asyncAdd

const asyncAdd = (x, y) => {
  return new Promise(resolve => {
     setTimeout(() => resolve(x + y), 1000)
  })
}

用法是:

asyncAdd(1,2).then(res => console.log(res)) // res : 3

那么对它进行备忘:

const asyncAdder = AsyncMemorize(asyncAdd)
asyncAdder(1,2).then(res1 => console.log(res1)) // 第一次等待1秒后输出res1: 3
asyncAdder(1,2).then(res1 => console.log(res1)) // 第二次不用等待1秒后就直接输出res1: 3

例子如下:


image.png

可以看到:
第一次执行asyncAdder(1,2).then(res1 => console.log(res1))的时候,
控制台先是打印Promise{<pending>} ,再打印结果3

第二次执行asyncAdder(1,2).then(res1 => console.log(res1))的时候,
控制台先是打印结果3 ,再打印Promise{<pending>}

实际应用场景:

前端需要通过ajax请求后端拿一个结果,这个结果是短时期或者长时期不会变的,那么就可以对这个结果进行备忘缓存,多次用到的时候只发一次请求,不用每次拿都发一次请求,起到节省带宽,减少用户等待时间、提升用户体验的作用。

总结

以上就是利用备忘模式分别对同步、异步结果进行缓存的使用方式,算是对计算性能的一个优化策略,值得参考。

相关文章

  • js性能优化-利用备忘模式进行结果缓存

    计算优化 对于不变的结果能缓存就尽量缓存,这样子就减少每次使用的时候进行多次计算,浪费性能。如: 同步结果:利用 ...

  • 性能优化

    性能优化 代码层面: 缓存利用 请求数量 请求带宽 总的来说 移动端性能优化 具体优化 加号操作符 事件委托 避免...

  • CPU缓存和内存屏障

    CPU性能优化手段 缓存 运行时指令重排 缓存 为了提高程序运行的性能,处理器大多会利用缓存来提高性能,而避免访问...

  • CPU缓存和内存屏障

    CPU性能优化手段 - 缓存 为了提高程序的运行性能, 现代CPU在很多方面对程序进行了优化例如: CPU高速缓存...

  • CPU缓存和内存屏障

    CPU性能优化手段-缓存 为了提高程序运行的性能,现代CPU在很多方面对程序进行了优化。例如:CPU高速缓存。尽可...

  • 简述http缓存

    简介 网站性能第一优化定律:优先考虑使用缓存优化性能。合理的使用缓存,对网站的性能优化的意义重大。以下对于缓存,都...

  • 3.CPU缓存和内存屏障

    cpu性能优化手段 缓存为了提高程序运行的性能,现代CPU在很多方面对程序进行了优化。例如:CPU高速缓存,尽可能...

  • 前端性能优化

    js性能小贴士——优化循环 前端网页与js性能优化 我总结的js性能优化的小知识 提高 web 应用性能之 Jav...

  • 前端性能 优化 大全

    js性能小贴士——优化循环 前端网页与js性能优化 我总结的js性能优化的小知识 提高 web 应用性能之 Jav...

  • 前端性能优化-缓存利用

    缓存分类 1.CDN缓存2.DNS缓存3.客户端缓存 1.CDN缓存 CDN可以理解分布世界各地的节点,当用户浏览...

网友评论

      本文标题:js性能优化-利用备忘模式进行结果缓存

      本文链接:https://www.haomeiwen.com/subject/rhjsoctx.html