• js-语言精粹-函数记忆


    函数可以将先前操作的结果记录在某个对象里,从而避免无谓的重复运算。这种优化方式被称为记忆(memoization)。JavaScript的对象和数组要实现这种优化是非常方便的。

    比如说,我们想要一个递归函数来计算Fibonacci数列。一个Fib数字是之前两个Fib数字的和。最前面的两个数字是0和1。

    var count=0;
    var fib=function(n){
        count++;
        return n<2?n:fib(n-1)+fib(n-2);
    };
    for(var i=0;i<=10;i++){
        console.log(fib(i))
    }
    
    //0
    //1
    //1
    //2
    //3
    //5
    //8
    //13
    //21
    //34
    //55
    
    count
    //453

    这样是可以工作的,但它做了很多无谓的工作,fib函数被调用了453次。如果我们让该函数具备记忆功能,就可以显著地减少运算量。

    我们在一个名为memo的数组里保存我们的存储结果,存储结果可以隐藏在闭包中。当函数被调用时,这个函数首先检查结果是否已经存在,如果已经存在,就立刻返回这个结果。

    var count=0;
    var fibonacci=function(){
        var memo=[0,1];
        var fib=function(n){
                    count++;
            var result=memo[n];
            if(typeof result!=='number'){
                result=fib(n-1)+fib(n-2);
                memo[n]=result;
            }
            return result;
        };
        return fib;
    }();
    
    for(var i=0;i<=10;i++){
        console.log(fibonacci(i))
    }
    //结果同上
    
    count
    //29

    这个函数返回同样的结果,但它只被调用了29次。

    我们可以把这种技术推而广之,编写一个函数来帮助我们构造带记忆功能的函数。memoizer函数取得一个初始的memo数组和formula函数。它返回一个管理memo存储和在需要时调用formula函数的recur函数。我们把这个recur函数和它的参数传递给formula函数:

    var memoizer=function(memo,formula){
        var recur=function(n){
            var result=memo[n];
            if(typeof result!=='number'){
                result=formula(recur,n);
                memo[n]=result;
            }
            return result;
        };
        return recur;
    };

    现在我们可以使用memoizer函数来定义fibonacci函数,提供其初始的memo数组和formula函数:

    var fibonacci=memoizer([0,1],function(recur,n){
        return recur(n-1)+recur(n-2);
    });

    通过设计这种产生另一个函数的函数,极大的减少了我们的工作量。例如,要产生一个可记忆的阶乘函数,我们只需提供基本的阶乘公式即可:

    var factorial=memoizer([1,1],function(recur,n){
        return n*recur(n-1);
    });
  • 相关阅读:
    前端面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)
    steps 步骤条、时间轴
    碰撞检测经典解决方案
    延迟渲染(Deferred Shading)技术详解
    配备透明触摸屏 看3D全息投影概念手机
    预渲染技术
    APK改之理(APK IDE)修改APK简单的入门教程
    如何获取显卡的GPU占用率和显存占用情况
    图像编辑之对比度调整 亮度对比度的算法公式
    别被你的双眼所欺骗 100张神奇的视觉欺骗图
  • 原文地址:https://www.cnblogs.com/zczhangcui/p/6410161.html
Copyright © 2020-2023  润新知