web-dev-qa-db-ja.com

Javascriptエンジンのテールコールは最適化されていますか?

Javascriptで実装した末尾再帰パス検索アルゴリズムがあり、(すべて?)ブラウザーがスタックオーバーフロー例外を取得する可能性があるかどうかを知りたいです。

90
clofresh

ECMAScript 4の仕様はもともとTCOのサポートを追加する予定でしたが、削除されました。

http://lambda-the-ultimate.org/node/3047

私の知る限り、JSの広く利用可能な実装は現在、自動TCOを行いません。ただし、これは役に立つかもしれません:

http://www.paulbarry.com/articles/2009/08/30/tail-call-optimization

基本的に、アキュムレータパターンを使用すると同じ効果が得られます。

47
Tim Sylvester

現時点では喜びはありませんが、ありがたいことに適切なテールコールがHarmonyに予定されています(ECMAScriptバージョン6) http://wiki.ecmascript.org/doku.php?id=harmony:proper_tail_calls

26
Mr Speaker

あなたが遭遇するほとんどすべてのブラウザは、「あまりにも多くの再帰」を禁止します。これは V8バグトラッカーのエントリ で、おそらく興味深い読み物です。

単純な自己再帰の場合は、おそらく、末尾呼び出しの除去を期待するのではなく、明示的な反復を使用する価値があります。

12
Hank Gay

テールコールの最適化は、今後ECMAScript 6 strictモードでサポートされる予定です。詳細については、 http://www.2ality.com/2015/06/tail-call-optimization.html を確認してください。

http://kangax.github.io/compat-table/es6/ で現在のエンジンサポートを確認してください。

現時点(2019年7月18日)では、次のエンジンがテールコールの最適化をサポートしています。

  • Safari> = 10
  • iOS> = 10
  • キノマXS6
  • デュテープ2.3

「実験的なJavaScript機能」フラグがオンになっている場合のサポート:

  • ノード6.5
  • Chrome 54/Opera 41 現在のバージョンのcompatテーブルにはリストされていません
11
Simon Zyx

テールコールの最適化が LispyScript で利用可能になり、javascriptにコンパイルされます。詳細については、こちらをご覧ください こちら

3
Santosh

現在、末尾再帰を認識するJS実装はありません。 ECMAScript 6で変更が行われています。他の人が言ったように、V8にはオープンチケットがあります。

ここでは、末尾再帰関数用にV8で生成されたアセンブラーを見ることができます

https://Gist.github.com/mcfedr/832e3553964a014621d5

それをclangがCで同じ関数をコンパイルした方法と比較してください

https://Gist.github.com/mcfedr/63ad08370d856bad3694

V8は再帰呼び出しを保持しますが、Cコンパイラーは末尾再帰を認識し、ループに変更しました

2
mcfedr