ES6尾递归优化堆栈溢出

时间:2017-03-14 14:04:32

标签: javascript recursion optimization ecmascript-6 stack-overflow

在es6中阅读了Dr Rauschmayer's description递归尾调用优化之后,我一直试图重新创建零堆栈'执行他详述的递归因子函数。

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

我还尝试通过在没有调试器的情况下调用函数来测试优化,而是将100000传递给阶乘函数。这会引发一个最大的堆叠'错误,这意味着它实际上没有被优化。

这是我的代码:

const factorial = (n, acc = 1) => n <= 1 ? acc : factorial(n - 1, n * acc)
console.log( factorial(100000) )

结果:

Uncaught RangeError: Maximum call stack size exceeded

2 个答案:

答案 0 :(得分:43)

Chrome中的JavaScript引擎V8在一段时间内获得了TCO支持,但截至此更新后的答案(2017年11月)已不再适用,截至撰写本文时,V8中的TCO尚无活跃开发,且没有计划好了。您可以在the V8 tracking bug for it中阅读详细信息。

TCO支持似乎已经在V8中达到了一个不错的水平,但由于几个原因(调试问题,错误)仍然落后于旗帜。但接下来发生了一些事情,尤其是the V8 team raised significant issues with TCO并且强烈支持名为syntactic tail calls (STCs)的规范更改,该更改要求有意地在源代码中标记尾部调用(例如,return continue doThat();)。不过,该提案于2017年7月成为inactive。同样在7月,由于没有完成TCO工作,V8团队从TurboFan *的源代码中删除了支持TCO的代码,否则它将受到bitrot的影响。 (例如,成为维持痛苦和虫子的来源。)

因此,目前(2017年11月)目前尚不清楚“看不见的”TCO是否会出现在V8中,无论某种STC是否会进入,或者是什么。 Chrome Platform Status page表示来自Mozilla(Firefox / SpiderMonkey)和Microsoft(Edge / Chakra)的支持TCO的“混合”公共信号,Safari正在提供TCO,并且Web开发人员对此功能“积极” 。我们会看到我们从这里走的路。如果在任何地方。

*(TurboFan = V8中当前最先进的JIT编译器,现在他们从Full-Codegen [JIT] + Crankshaft [积极优化JIT]到Ignition [interpreter +]和TurboFan [积极优化] switched JIT])

答案 1 :(得分:9)

V8(Chrome的JS引擎)团队目前尚未实施TCO。它已从最新版本(see this thread)中删除。

主流浏览器only Safari has actually implemented the feature

在Node.JS版本8及更高版本中,TCO is not available

实施TCO可能会有一些希望:在recent WebAssembly meeting中,Google和所有其他在场的人士对于进一步探索TCO实施是中立或积极的。