读过Rauschmayer 博士的描述关于 es6 中的递归尾部调用优化,我一直在尝试重新创建他详细介绍的递归阶乘函数的“零堆栈”执行。
使用 Chrome 调试器在堆栈帧之间步进,我发现尾部优化没有发生,并且正在为每个递归创建一个堆栈帧。
我还尝试通过在没有调试器的情况下调用函数来测试优化,而是传递100000
到阶乘函数。这会引发“最大堆栈”错误,这意味着它实际上并未优化。
这是我的代码:
const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc)
console.log( factorial(100000) )
Result:
Uncaught RangeError: Maximum call stack size exceeded
Chrome 中的 JavaScript 引擎 V8 有一段时间支持 TCO,但截至此更新答案(2017 年 11 月),它不再支持,V8 中没有针对 TCO 的积极开发,也没有计划。您可以阅读详细信息V8 跟踪错误.
V8 中的 TCO 支持似乎一度达到了不错的水平,但由于多种原因(调试问题、错误)仍然处于落后状态。但后来发生了几件事,尤其是V8 团队提出了 TCO 的重大问题并强烈支持一项名为句法尾部调用 (STC)这将需要有意在源代码中标记尾部调用(例如,return continue doThat();
)。该提案成为inactive不过,在 2017 年 7 月。同样在 7 月,由于没有完成 TCO 工作,V8 团队从 TurboFan* 的源代码中删除了支持 TCO 的代码,因为否则它会受到 bitrot 的影响。 (例如,成为维护难题和错误来源。)
因此,目前(2017 年 11 月)尚不清楚“隐形”TCO 是否会出现在 V8 中,是否会出现某种 STC,或者什么。这Chrome 平台状态页面因为这表明 Mozilla (Firefox/SpiderMonkey) 和 Microsoft (Edge/Chakra) 在支持 TCO 方面发出了“混合”的公开信号,Safari 附带了 TCO,并且 Web 开发人员对该功能持“积极”态度。我们将看看我们从这里走向何方。如果在任何地方。
*(TurboFan = V8 中当前最先进的 JIT 编译器,现在他们已经switched从 Full-Codegen [JIT] + Crankshaft [积极优化 JIT] 到 Ignition [解释器+] 和 TurboFan [积极优化 JIT])
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)