ES6尾递归优化堆栈溢出

Sam*_*lan 32 javascript stack-overflow optimization recursion ecmascript-6

阅读了Rauschmayer博士对es6中递归尾调用优化的描述之后,我一直试图重新创建他详细说明的递归因子函数的"零堆栈"执行.

使用Chrome调试器在堆栈帧之间切换,我发现尾部优化没有发生,并且正在为每次递归创建堆栈帧.

我也尝试通过在没有调试器的情况下调用函数来测试优化,而是传递100000给阶乘函数.这会引发"最大堆栈"错误,这意味着它实际上并未进行优化.

这是我的代码:

const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc)
console.log( factorial(100000) )
Run Code Online (Sandbox Code Playgroud)

结果:

Uncaught RangeError: Maximum call stack size exceeded
Run Code Online (Sandbox Code Playgroud)

T.J*_*der 51

V8是Chrome中的JavaScript引擎,有一段时间的TCO支持,但是从更新后的答案(2017年11月)开始,它已经不再适用了.在撰写本文时,V8中的TCO没有积极的开发,也没有计划.您可以阅读V8跟踪错误中的详细信息.

TCO支持似乎已经在V8中达到了一个不错的水平,但由于几个原因(调试问题,错误)仍然落后于旗帜.但随后发生了一些事情,尤其是V8团队提出了TCO的重大问题,并强烈支持称为句法尾部调用(STC)的规范更改,这需要有意地在源代码中标记尾部调用(例如return continue doThat();).该提案成为不活动在七月2017年,虽然.同样在7月份,由于没有完成TCO工作,V8团队从TurboFan*的源代码中删除了支持TCO的代码,否则它将受到bitrot的影响.(例如,成为一种维持痛苦和虫子的来源.)

因此,目前(2017年11月)尚不清楚"看不见的"TCO是否会出现在V8中,无论某种STC是否会进入,或者是什么.在Chrome平台状态页面为这表明在支持TCO从Mozilla的(火狐/ SpiderMonkey的)和微软(边缘/查克拉)"混合"的公共信号,Safari浏览器与TCO出货,而Web开发人员是"积极的"了解的功能.我们会看到我们从这里走的路.如果在任

*(涡轮风扇=在V8当前尖端JIT编译器,现在他们已经切换从全代码生成[JIT] +曲轴[侵略性优化JIT]至点火[解释+]和涡扇[侵略性优化JIT])

  • 不幸的是,Chrome(以及互联网)可能永远不会有正确的尾部调用实现。请参阅下面的答案。 (2认同)
  • @TJCrowder 你是对的,它可能并没有完全死在水中 - 在这次 WebAssembly 会议上,没有一个出席的团体投票反对进一步考虑(所有人都是中立或积极的)。感谢您的鼓励,让我们多看一点!https://github.com/WebAssembly/meetings/blob/master/2017/CG-07.md#tail-call (2认同)

Luk*_*ams 9

V8(Chrome的JS引擎)团队目前尚未实施TCO.它被淘汰出最新版本(见本帖).

在主流浏览器中,只有Safari实际实现了该功能.

在Node.JS版本8及更高版本中,TCO不可用.

TCO的实施可能有一些希望:在最近的一次WebAssembly会议上,Google和所有其他在场的团体对于进一步探索TCO实施是中立或积极的.