97

does-the-jvm-prevent-tail-call-optimizationsから2 年後、プロトタイプの 実装があるようで、MLVMはこの機能をしばらくの間「proto 80%」と​​してリストしています。

テール コールをサポートすることに Sun/Oracle 側からの積極的な関心はありませんか、それとも、 JVMで言及されているように、テール コールは「[...]すべての機能の優先順位リストで 2 位になる運命にある [...]」だけなのでしょうか。言語サミット

誰かが MLVM ビルドをテストして、それがどれだけうまく機能するか (もしあったとしても) の印象を共有できれば、私は本当に興味があります。

更新: Avianなどの一部の VMは、問題なく適切な末尾呼び出しをサポートすることに注意してください。

4

5 に答える 5

33

Java コードの診断: Java コードのパフォーマンスの向上( alt ) では、JVM が末尾呼び出しの最適化をサポートしない理由について説明しています。

しかし、末尾再帰関数を単純なループに自動的に変換する方法はよく知られていますが、Java 仕様ではこの変換を行う必要はありません。おそらく、これが要件ではない理由の 1 つは、一般に、オブジェクト指向言語では変換を静的に行うことができないためです。代わりに、末尾再帰関数から単純なループへの変換は、JIT コンパイラによって動的に行われる必要があります。

次に、変換されない Java コードの例を示します。

したがって、リスト 3 の例が示すように、静的コンパイラーが Java コードの末尾再帰の変換を実行しながら、言語のセマンティクスを維持することは期待できません。代わりに、JIT による動的コンパイルに依存する必要があります。JVM によっては、JIT がこれを行う場合と行わない場合があります。

次に、JITがこれを行うかどうかを判断するために使用できるテストを提供します。

当然、これは IBM の論文であるため、プラグが含まれています。

いくつかの Java SDK を使用してこのプログラムを実行したところ、驚くべき結果が得られました。バージョン 1.3 の Sun の Hotspot JVM で実行すると、Hotspot が変換を実行しないことがわかります。デフォルト設定では、私のマシンでは 1 秒もかからずにスタック スペースが使い果たされます。一方、バージョン 1.3 用の IBM の JVM は問題なく動作し、この方法でコードを変換していることを示しています。

于 2010-09-10T03:15:45.083 に答える
32

Java で TCO を実装しない (そしてそれが難しいと見なされている) 理由の 1 つは、JVM のパーミッション モデルがスタックに依存するため、末尾呼び出しでセキュリティの側面を処理する必要があることです。

これは Clements と Felleisen [1] [2] によって障害ではないことが示されたと思います。また、質問で言及されている MLVM パッチもそれを扱っていると確信しています。

これがあなたの質問に答えていないことは承知しています。興味深い情報を追加するだけです。

  1. http://www.ccs.neu.edu/scheme/pubs/esop2003-cf.pdf
  2. http://www.ccs.neu.edu/scheme/pubs/cf-toplas04.pdf
于 2011-02-23T21:29:33.310 に答える
15

すでにご存知かもしれませんが、Java 言語は実際にスタック トレースをプログラマーに公開するため、この機能は思ったほど簡単ではありません。

次のプログラムを検討してください。

public class Test {

    public static String f() {
        String s = Math.random() > .5 ? f() : g();
        return s;
    }

    public static String g() {
        if (Math.random() > .9) {
            StackTraceElement[] ste = new Throwable().getStackTrace();
            return ste[ste.length / 2].getMethodName();
        }
        return f();
    }

    public static void main(String[] args) {
        System.out.println(f());
    }
}

これには「テールコール」がありますが、最適化されていない可能性があります。(最適化されている場合でも、プログラムのセマンティクスがコール スタックに依存しているため、コール スタック全体の簿記が必要です。)

基本的に、これは下位互換性を保ちながらこれをサポートするのが難しいことを意味します。

于 2010-09-07T14:09:52.670 に答える
13

Java は、あなたが想像できる最も機能の少ない言語です (まあ、そうかもしれません!) が、これはScalaのような JVM 言語にとって大きな利点となります。

私の観察では、JVM を他の言語のプラットフォームにすることは、Sun の優先順位リストの最上位にあるようには見えませんでした。現在は Oracle にとってもそうです。

于 2010-09-01T09:11:45.903 に答える