ES6尾递归优化堆栈溢出
读过了Rauschmayer博士对es6中递归尾部调用优化的描述后,我一直试图重新创建他详细描述的递归阶乘函数的'零栈'执行。
使用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
Chrome浏览器中的JavaScript引擎V8有一段时间有TCO支持,但截至本次更新的答案(2017年11月)已不复存在,截至本文撰写时,V8没有积极的TCO开发,也没有计划。 你可以阅读V8跟踪错误的细节。
总体拥有成本支持似乎已经达到了V8的一个相当的水平,但由于几个原因(调试问题,错误)仍然落后于旗帜。 但后来发生了几件事情,尤其是V8团队提出了TCO的重大问题,强烈支持称为句法尾部调用(STC)的规范变化,这将需要故意在源代码中标记尾部调用(例如, return continue doThat();
)。 不过,该提案在2017年7月失效。 同样在7月份,由于没有完成TCO工作,V8团队从TurboFan *的源代码中删除了支持TCO的代码,因为否则它会受到bit。。 (例如,成为维护痛苦和bug的根源。)
因此,目前(2017年11月),目前还不清楚“无形”TCO会在V8中出现,无论某种类型的STC是否会进入或出现在哪里。 此Chrome平台状态页面显示了Mozilla(Firefox / SpiderMonkey)和微软(Edge / Chakra)在支持TCO,Safari随TCO出货以及Web开发人员对该功能“积极”的“混合”公共信号。 我们会看到我们从这里走到哪里。 如果有的话。
*(TurboFan = V8中目前尖端的JIT编译器,现在他们已经从完全代码版[JIT] +曲轴[积极优化JIT]转换为Ignition [interpreter +]和TurboFan [积极优化JIT])
V8(Chrome的JS引擎)团队暂时没有实施TCO。 它被剥离出最新版本(请参阅此主题)。
在主要浏览器中,只有Safari实际实现了该功能。
在Node.JS版本8和更高版本中,TCO不可用。
可能会有一些TCO的实施希望:在最近的WebAssembly会议上,Google和所有其他团队对于进一步探索TCO实施持中立态度或积极态度。
链接地址: http://www.djcxy.com/p/80513.html