java支持尾递归优化么,js 一个神奇的尾递归优化

参考

测试代码

const getList = (size) => Array(size).fill(1);

const sum = (list) => {

if (list.length === 1) return list[0];

const prev = list.pop();

return prev + sum(list);

};

const sumAsync = async (list) => {

await undefined;

if (list.length === 1) return list[0];

const prev = list.pop();

return prev + (await sumAsync(list));

};

console.log(getList(10));

sumAsync(getList(10)).then(console.log);

console.log(sum(getList(10)));

async function test(size) {

sumAsync(getList(size)).then((data) => {

console.log("async", data);

console.log(sum(getList(size)));

});

}

test(20000);

异步的可以正常执行, 但是同步的会爆栈

c8550270947ebc48b6d2395ae727df7d.png

同步代码, 栈空间是O(n) 的, 在列表比较大的情况下会直接把栈内存占满后报错

bf76a94f749214aa21384f7df7116ab5.png

异步代码, 首先直觉上也是O(n)的, 但是确实可以成功输出

252befb3958a6a74a9ed400d4bd93a48.png

作者的说法, 即async将栈内存转移到堆中, 由于堆内存比栈大得多, 所以即使是小数据的O(n), 堆内存也是可以撑住的

85af5473c8ae0275d5c3e811551c4d15.png

左边是同步的, 执行是一样的 , 右边会变化, 也就是说转到了堆上

d5cc25c141ea9cdab6eaa73e712335f1.png

两个的区别只是注释了那个优化一行导致的

const async_hooks = require("async_hooks")

let index = 0

let print_buffer = ""

/**

* async hooks会追踪async调用,

* 而console.log使用异步输出,

* 所以这里使用同步方法模拟console

*/

function println(log) {

print_buffer += log + "\n"

}

/* 创建钩子 */

async_hooks.createHook({

init(asyncId, type, triggerAsyncId) {

const eid = async_hooks.executionAsyncId()

println("init: *********************************")

println("init: triggerAsyncId " + triggerAsyncId)

println("init: executionAsyncId " + eid)

println("init: asyncId " + asyncId)

println("init: type " + type)

}

})

.enable()

/*********** 测试区 **********/

async function A() {

/* 为了观察方便只执行2次 */

println("A: runing")

index += 1

if (index === 2) return undefined

// 有优化递归

// await undefined

return await A()

}

/*********** 测试区 **********/

A().then(() => {

console.log(print_buffer)

})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值