js Memoization 针对cpu密集型运算 提高运行速度

项目中需要用到 大计算量 耗时的js运算。

js是单线程模型 ,优点是异步操作,对于nodejs来说可以处理高并发的任务。 但对密集型的cpu运算,异步解决不了问题,正确的来说还是该新开个线程处理。

对前端开发来说 执行大计算量 耗时的js运算   不仅会阻塞ui线程 从而导致浏览器进入僵死状态,崩溃,同时部分浏览器还会跳弹窗询问是否停止 执行的脚本。

前端 有基于HTML5 的web workers 创建新的线程

本来是考虑用 web workers 。但是  两方面

1  新开的线程 不能操作dom (这是可以理解)

2  令人发指的api, web weorkers 的新开的线程必须在一个独立的文件中 ,传url以异步方式调用,这是我非常不能接受,破坏了我项目模块化的结构。  传说 ecmascript7  会有Multi-Threading  支持多线程  默默期待吧

 

放弃 web  workers意外 发现 underscore  提供了 Memoize  方法

原理是以 内存作为缓存 以内存空间换cpu的执行时间的 提高运行速度的方法。

magic  先看效果

以斐波那契数组 为例

当n>40  firfox  ie 都会弹出停止脚本的提示框,浏览器进入僵死状态,ui线程被阻塞

var fibonacci =function(n) {
    return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);
};
console.log(fibonacci (40))

 

使用 Memoize  方法, 成功执行 没有僵死,ui线程没有阻塞

var fibonacci = _.memoize(function(n) {
    return n <2? n : arguments.callee(n -1) + arguments.callee(n -2);
});

document.write( fibonacci (40))

 

源码分析

 _.memoize = function(func, hasher) {
    var memoize = function(key) {
      var cache = memoize.cache;
      var address = hasher ? hasher.apply(this, arguments) : key;
      if (!_.has(cache, address)) cache[address] = func.apply(this, arguments);
      return cache[key];
    };
    memoize.cache = {};
    return memoize;
  };

  以参数作为键进行缓存,被执行的结果按参数缓存在memo对象上,用内存空间 换cpu执行时间

 

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。