JavaScript 引擎尾部调用 (TCO) 是否经过优化?
我有一个用 JavaScript 实现的尾递归寻路算法,想知道是否有(所有?)浏览器可能会出现堆栈溢出异常。
I have a tail recursive pathfinding algorithm that I've implemented in JavaScript and would like to know if any (all?) browsers would possibly get stack overflow exceptions.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
ECMAScript 4 规范最初打算添加对 TCO 的支持,但后来被删除:
否JavaScript 中是否有更多尾部调用?
截至 2010 年,目前还没有广泛可用的 JavaScript 实现自动进行 TCO。
请参阅评论以了解更多最新更新。
The ECMAScript 4 specification was originally going to add support for TCO, but it was dropped:
No more tail calls in JavaScript?
As of 2010, no widely-available implementations of JavaScript currently do automatic TCO.
See comments for more recent updates.
目前不高兴,但值得庆幸的是,Harmony(ECMAScript 版本 6)将进行适当的尾部调用
http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls
No joy for the moment, but thankfully proper tail calls are slated for Harmony (ECMAScript version 6)
http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls
未来 ECMAScript 6 严格模式将支持尾调用优化。检查 http://www.2ality.com/2015/06/tail -call-optimization.html 了解详细信息。
检查 http://kangax.github.io/compat-table/es6/对于当前的引擎支持。
目前 (18-07-2019) 以下引擎支持尾部调用优化:
如果打开“实验性 JavaScript 功能”标志,则支持:
Chrome 54 / Opera 41当前版本的兼容表已不再列出Tail call optimization will be supported In ECMAScript 6 strict mode in the future. Check http://www.2ality.com/2015/06/tail-call-optimization.html for details.
Check http://kangax.github.io/compat-table/es6/ for current engine support.
At the moment (18-07-2019) the following engines support tail call optimization:
support if "experimental JavaScript features"-flag is turned on:
Chrome 54 / Opera 41Current version of the compat table does not list it anymore几乎您遇到的每个浏览器都会因“递归过多”而呕吐。这是V8 bug 跟踪器中的条目,您可能会感兴趣阅读。
如果它是简单的自递归,那么可能值得努力使用显式迭代而不是希望消除尾部调用。
Pretty much every browser you encounter will barf on "too much recursion". Here's an entry in the V8 bug tracker that will probably be interesting reading.
If it's simple self-recursion, it's probably worth the effort to use explicit iteration rather than hoping for tail-call elimination.
LispyScript 现在提供尾部调用优化,可编译为 JavaScript。您可以在此处阅读更多相关信息。
Tail call optimization is now available in LispyScript which compiles to JavaScript. You can read more about it here.
目前没有 JavaScript 实现识别尾递归。 ECMAScript 6 中正在进行更改,正如其他人所说,是 V8 上的开放票证。
在这里您可以看到 V8 为尾递归函数生成的汇编程序:
V8 如何编译递归的示例
将其与 Clang 在 C 中编译相同函数的方式进行比较
C 编译器尾递归示例
V8 保留了递归调用,而 C编译器已经识别出尾递归并将其更改为循环。
Currently no JavaScript implementations recognise tail recursion. Changes are being made in ECMAScript 6, and as others have said, there is an open ticket on V8.
Here you can see V8's generated assembler for a tail recursion function:
Example of how V8 compiles recursion
Compare that to how Clang has compiled the same function in C
Example of C compiler tail recursion
V8 retains the recursive call, whereas the C compiler has recognised the tail recursion and changed it into a loop.