js Memoization 优化运行速度

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

 

Memoize 是一个优化方法 ,对耗时的递归运算,漫长的查找运算的结果进行缓存,使运行时间最小化

原理是缓存先前的结果计算值从而可以避免需要重新计算   提高运行速度的方法。

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))

 

著名underscore 的 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执行时间

 

详解  :

Example1 :  

function square(num){

    return num*num;

}



square(10) //100
square(100)

如上所示,每次调用square方法,都会重新计算。如果这是一个递归 耗时的任务 缓存就很重要可以很好的优化执行时间。 如下所示

function square(num){

  var result = '';

  if(!square.cache[num]){ 

     console.log("Computing value...");

     result = num*num;

     square.cache[num] = result;  

  }

 

  return square.cache[num];

 

}

square.cache = {}

square(10) //第一次调用 计算结果 缓存结果

square(10) //第二次开始从缓存中返回结果。

square(20) // 如果一个新值,再次计算。

 创建一个普通的js对象,以参数作为键,缓存结果存在键值上.

 

Example2  (升级)

square的arguments,可能是数组或者json对象 

var square = function(num){

    var key = JSON.stringify(Array.prototype.slice.call(num));



    if(!square.cache[key]){

    var result={};

    //Computation

        console.log("Computing value..."); 

        result = num*num;

    square.cache[key] = result;

}



return square.cache[key];

}



square.cache = {};

  

  

  

  缓存是个很好的优化js执行速度的方法,不但可以缓存数据运算的结果,前端用到最多的是类似backbone一类mvc 前端框架,缓存视图对象的实例。

  

 

你可能感兴趣的:(js)