zoukankan      html  css  js  c++  java
  • 使用缓存来提高开发性能

    最近浏览关于性能的博客比较多,

    无论是拼图/懒加载等傻瓜式优化,还是逻辑上的选用设计模式等系统优化,

    感觉都是挺好玩的,今天就来讲讲缓存在网站开发中的重要性。

    计算斐波那契数列,也叫黄金分割数列(1,1,2,3,5,8,13...),同时也就是兔子繁衍问题,每一项等于前两项之和,

    当然,数列项的其他操作就不在今天讨论的范围内了,比如 1/1=1, 1/2=0.5, 2÷3=0.666, ... 144÷233=0.618025 无限趋近于 0.618(黄金分割比)等,

    计算第 n 个斐波那契数列项就需要用到下面这样的程序,

    var count = 0;
    function fib(n) {
      count++;
      if(n === 0 || n === 1) return 1;
      return fib(n-2) + fib(n - 1);
    }
    console.log(fib(40), count); // 运行了 331160281 次
    

    显然这样来做理论上是对的,但计算量细思极恐,

    如果我们可以把计算过了的项存在缓存里,不用计算下一项时又计算一次它,是不是能优化很多呢...

    var count = 0;
    var fib = (function() {
        var cache = [];
        return function(n) {
            count++;
            if(cache[n] !== undefined) {
                return cache[n];
            }
            if(n === 0 || n === 1) {
                cache[n] = 1;
                return cache[n];
            }
            var temp = arguments.callee(n - 1) + arguments.callee(n - 2);
            cache[n] = temp;
            return cache[n];
        };
    })();
    console.log(fib(40), count); // 运行了 79 次
    

    发现一般使用递归都会使运行时间增长很多,于是乎,写了下面这段代码,

    将缓存模式进行了封装,于是乎,无论是简单递归还是斐波那契数列都可以很轻易的提升性能了

    // 测试性能
    function testFunctionTime(fn, label) {
        console.time(label);
        if (fn) fn();
        console.timeEnd(label);
    }
    // 封装缓存机制
    function useCache(fn) {
        var cache = {};
        return function(){
            var key = arguments.length + Array.prototype.join.call(arguments, ",");
            if (key in cache) return cache[key];
            else return cache[key] = fn.apply(this, arguments);
        }
    }
    // 斐波那契数列
    function fn1() {
        var count = 0;
        var fib = function(n) {
            count++;
            if(n === 0 || n === 1) return 1;
            return fib(n - 1) + fib(n - 2);
        };
        console.log(fib(40), count);
    }
    function fn2() {
        var count = 0;
        var fib = useCache(function(n) {
            count++;
            if(n === 0 || n === 1) return 1;
            return fib(n - 1) + fib(n - 2);
        });
        console.log(fib(40), count);
    }
    
    testFunctionTime(fn1, '无缓存');
    testFunctionTime(fn2, '有缓存');

    嗯,效果非常 nice 哟

  • 相关阅读:
    对我影响最大的三位导师
    global与nonlocal
    random模块
    time模块
    datetime模块
    sys模块
    os模块
    collection模块
    hashlib模块
    pickle模块
  • 原文地址:https://www.cnblogs.com/foreverZ/p/5981682.html
Copyright © 2011-2022 走看看