简体   繁体   English

是否有任何 JavaScript 引擎尾调用 (TCO) 优化?

[英]Are any JavaScript engines tail call (TCO) optimized?

我有一个用 JavaScript 实现的尾递归寻路算法,想知道是否有任何(所有?)浏览器可能会出现堆栈溢出异常。

The ECMAScript 4 specification was originally going to add support for TCO, but it was dropped: ECMAScript 4 规范原本打算添加对 TCO 的支持,但它被删除了:

No more tail calls in JavaScript? JavaScript 中不再有尾调用?

As far as I know, no widely-available implementations of JavaScript currently do automatic TCO.据我所知,目前还没有广泛使用的 JavaScript 实现可以实现自动 TCO。 This may be of use to you, though:不过,这可能对您有用:

Tail Call Optimization 尾调用优化

Essentially, using the accumulator pattern accomplish the same effect.本质上,使用累加器模式可以实现相同的效果。

暂时没有快乐,但幸运的是,Harmony(ECMAScript 版本 6)有适当的尾调用http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls

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.这是V8 错误跟踪器中的一个条目,可能会很有趣。

If it's simple self-recursion, it's probably worth the effort to use explicit iteration rather than hoping for tail-call elimination.如果它是简单的自递归,那么使用显式迭代而不是希望消除尾调用可能是值得的。

Tail call optimization will be supported In ECMAScript 6 strict mode in the future.未来将在 ECMAScript 6 严格模式中支持尾调用优化。 Check http://www.2ality.com/2015/06/tail-call-optimization.html for details.查看http://www.2ality.com/2015/06/tail-call-optimization.html了解详情。

Check http://kangax.github.io/compat-table/es6/ for current engine support.检查http://kangax.github.io/compat-table/es6/以获得当前的引擎支持。

At the moment (18-07-2019) the following engines support tail call optimization:目前(18-07-2019)以下引擎支持尾调用优化:

  • Safari >= 10 Safari >= 10
  • iOS >= 10 iOS >= 10
  • Kinoma XS6奇诺玛XS6
  • Duktape 2.3杜克磁带 2.3

support if "experimental JavaScript features"-flag is turned on:如果打开“实验性 JavaScript 功能”标志,则支持:

  • Node 6.5节点 6.5
  • Chrome 54 / Opera 41 Current version of the compat table does not list it anymore Chrome 54 / Opera 41当前版本的兼容性表不再列出

Tail call optimization is now available in LispyScript which compiles to JavaScript.现在可以在编译为 JavaScript 的LispyScript中使用尾调用优化。 You can read more about it here .您可以在此处阅读更多相关信息。

Currently no JavaScript implementations recognise tail recursion.目前没有 JavaScript 实现识别尾递归。 Changes are being made in ECMAScript 6 , and as others have said, there is an open ticket on V8 . ECMAScript 6正在发生变化,正如其他人所说, V8上有一张公开票。

Here you can see V8's generated assembler for a tail recursion function:在这里你可以看到 V8 为尾递归函数生成的汇编程序:

Example of how V8 compiles recursion V8 如何编译递归的例子

Compare that to how Clang has compiled the same function in C将其与Clang如何在 C 中编译相同的函数进行比较

Example of C compiler tail recursion C 编译器尾递归示例

V8 retains the recursive call, whereas the C compiler has recognised the tail recursion and changed it into a loop. V8 保留递归调用,而 C 编译器已识别尾递归并将其更改为循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM