JavaScript 斐波拉切数列优化记录

本文通过对比不同算法实现斐波那契数列,包括原始递归、数组优化及memoization方案,展示了如何显著提升JavaScript算法效率,并探讨了console.log()对性能的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

凤头

几天前,我在纠结以后开发究竟要使用Safari还是Chrome的时候,发现了一篇文章:
用最简单易懂的道理告诉你,为什么JavaScript在现代引擎(V8,JavaScriptCore)下,能表现出卓越性能!

文章中使用斐波拉切递归算法测试了浏览器的性能,其代码如下:

    let num = 40;
    let startDate = new Date().getTime();
    let result = logfs(num);
    let endDate = new Date().getTime();

    console.log("time:" + ((endDate - startDate) / 1000) + "s", "result:" + result);

    function logfs(num) {
        let rsString = "";
        for (let i = 1; i <= num; i++) {
            let rs = fs(i);
            if (i === 1) {
                rsString = rsString + rs;
            } else {
                rsString = rsString + "," + rs;
            }
            console.log(rs);
        }
        return rsString;
        function fs(n) {
            if (n <= 2) {
                return 1;
            } else {
                return fs(n - 1) + fs(n - 2);
            }
        }
    }

我也简单的在Safari和Chrome中测试了一下,计算40项,在Chrome中大概需要3.5s,在Safari中大概需要2.5s。

计算个兔子数列竟然需要这么久,于是就引出了我对斐波拉切数列算法的优化。

猪肚

使用数组优化算法

对于优化,我首先想到的是抛弃递归,转而使用一个数组存储每次的结果,代码如下:

 let num = 40;
    let res = [];

    function main(num) {
        for (let i = 0; i < num; i++) {
            if (i <= 2) {
                res [i] = 1;
            }else {
                res [i] = res[i - 1] + res[i - 2];
            }
            console.log(res[i]);
        }
    }

    let startDate = new Date().getTime();
    main(num);
    let endDate = new Date().getTime();

    console.log("time:" + ((endDate - startDate) / 1000) + "s", "result:" + res);

经测试,计算40项,其时间开销大概在0.015s左右;计算400项,其时间开销大概在0.085s左右。

memoization方案优化算法

使用数组计算的这个结果,大概还能让我满意,但总觉得还是有些慢,于是我发现了这样一篇文章:
斐波那契数列求和的js方案以及优化

文中介绍了多种优化方案,我最感兴趣的是其中的使用 memoization方案 优化递归。
仿照他的方案,我简单写了一下,代码如下:

let fibonacci = (function () {
        let memory = {};
        return function (n) {
            if (n === 0 || n === 1) {
                return n;
            }
            if (memory[n - 2] === undefined) {
                memory[n - 2] = fibonacci(n - 2)
            }
            if (memory[n - 1] === undefined) {
                memory[n - 1] = fibonacci(n - 1)
            }
            return memory[n] = memory[n - 1] + memory[n - 2]
        }
    })();

    function speedTest(n) {
        let startDate = new Date().getTime();
        let mem = fibonacci(n);
        let endDate = new Date().getTime();
        console.log("time:" + ((endDate - startDate) / 1000) + "s", mem);
    }

    speedTest(40);

结果发现这次计算40项和计算400项,时间基本为0,偶尔一次0.001s。
这个时间就很舒服了。

还有什么原因影响了性能?

细心的我发现,数组的方式打印出了每次计算的结果,而memoization方案没有打印。所以,console.log() 会不会是影响性能的原因呢?
于是我去掉了数组方案中的console.log() ,代码如下:

let num = 400;
    let res = [];

    function main(num) {
        for (let i = 0; i < num; i++) {
            if (i <= 2) {
                res [i] = 1;
            }else {
                res [i] = res[i - 1] + res[i - 2];
            }
            // console.log(res[i]);
        }
    }

    let startDate = new Date().getTime();
    main(num);
    let endDate = new Date().getTime();

    console.log("time:" + ((endDate - startDate) / 1000) + "s", "result:" + res);

结果,无论是计算40项还是计算400项,其时间开销和memoization方案一样:基本为0s,偶尔一次0.001s 。
果然是console.log() 影响力性能!

神仙打架

为了比较 memoization方案 和 数组方案的性能差异,进行了如下实验:
//TODO

豹尾

//TODO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值