ES6尾递归优化堆栈溢出 [英] ES6 Tail Recursion Optimisation Stack Overflow

查看:120
本文介绍了ES6尾递归优化堆栈溢出的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

已阅读劳斯迈耶博士对递归尾部调用优化的描述在es6中,此后我一直在尝试重新创建他详细介绍的递归阶乘函数的零堆栈"执行.

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

我还尝试了通过不使用调试器的函数来测试优化的方法,而是将100000传递给阶乘函数.这将引发最大堆栈"错误,这实际上表明该错误未得到优化.

Having read Dr Rauschmayer's description of recursive tail call optimisation in es6, I've since been trying to recreate the 'zero-stack' execution of the recursive factorial function he details.

Using the Chrome debugger to step between stack frames, I'm seeing that the tail optimisation is not occurring and a stack frame is being created for each recursion.

I've also tried to test the optimisation by calling the function without the debugger, but instead passing 100000 to the factorial function. This throws a 'maximum stack' error, which implies that it is, in fact, not optimised.

这是我的代码:

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, the JavaScript engine in Chrome, had TCO support for a while, but as of this updated answer (November 2017) it no longer does and as of this writing, there is no active development on TCO in V8, and none is planned. You can read the details in the V8 tracking bug for it.

TCO支持似乎已经在V8中达到了一个不错的水平,但由于多种原因(调试问题,错误)而仍然落后.但是随后发生了几件事,尤其是 V8团队成立了TCO方面的重大问题,并强烈支持称为语法尾调用(STC)的规范更改要求在源代码中故意标记尾调用(例如,return continue doThat();).不过,该提案在2017年7月成为无效.同样在7月份,由于没有进行TCO工作,V8团队从TurboFan *的源代码中删除了支持TCO的代码,否则该代码可能会受到破坏. (例如,成为维护难题和错误源).

TCO support seems to have reached a decent level in V8 at one point, but remained behind a flag for several reasons (debugging issues, bugs). But then several things happened, not least that the V8 team raised significant issues with TCO and strongly supported a spec change called syntactic tail calls (STCs) that would require that tail calls be flagged in source code intentionally (e.g., return continue doThat();). That proposal became inactive in July 2017, though. Also in July, with no TCO work being done, the V8 team removed the code for supporting TCO from the source for TurboFan* as it would otherwise be subject to bitrot. (E.g., become a maintenance pain and source of bugs.)

因此,目前(2017年11月)尚不清楚V8中是否会出现隐形" TCO,是否会出现某种类型的STC或什么. Chrome平台状态页面表示来自Mozilla(Firefox/SpiderMonkey)和Microsoft(Edge/Chakra)支持TCO,Safari随TCO一起提供,并且Web开发人员对该功能持肯定态度".我们将看到我们从这里出发的去向.如果有的话.

So at present (Nov 2017) it's not clear that "invisible" TCO will ever be in V8, whether some kind of STCs will come in, or what. The Chrome Platform Status page for this indicates "mixed" public signals from Mozilla (Firefox/SpiderMonkey) and Microsoft (Edge/Chakra) on supporting TCO, that Safari is shipping with TCO, and that web developers are "positive" about the feature. We'll see where we go from here. If anywhere.

*(TurboFan = V8中当前的最新JIT编译器,现在他们

* (TurboFan = the current cutting-edge JIT compiler in V8, now they've switched from Full-Codegen [JIT] + Crankshaft [aggressive optimizing JIT] to Ignition [interpreter+] and TurboFan [aggressive optimizing JIT])

这篇关于ES6尾递归优化堆栈溢出的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆