1. ホーム
  2. c#

[解決済み] なぜ.NET/C#は末尾再帰を最適化しないのですか?

2022-09-16 20:37:59

質問

私は この質問 を見つけました。なぜC#は可能な限り末尾再帰を最適化しないのですか?

具体的な事例として、なぜこのメソッドはループに最適化されないのでしょうか ( Visual Studio 2008 32-bit, if that matters)?

private static void Foo(int i)
{
    if (i == 1000000)
        return;

    if (i % 100 == 0)
        Console.WriteLine(i);

    Foo(i+1);
}

どのように解決するのですか?

JIT コンパイルは、コンパイル フェーズにあまり時間をかけない (したがって、短期間のアプリケーションを大幅に遅くする) ことと、標準の先行時間コンパイルで長期的にアプリケーションの競争力を維持するために十分な分析を行わないことのバランスを取るのが難しい作業です。

興味深いことに NGen のコンパイルステップでは、より積極的に最適化することを目標としていません。これは、JIT と NGen のどちらがマシン コードを担当したかに動作が依存するようなバグを発生させたくないだけなのでしょう。

その CLR 自体はテールコールの最適化をサポートしますが、言語固有のコンパイラは、関連する オペコード を生成する方法を知っている必要があり、JIT はそれを尊重する必要があります。 F#の fscは関連するオペコードを生成します(ただし、単純な再帰の場合は、全体を while ループに直接変換する)。C#のcscはそうではありません。

参照 このブログ記事 を参照してください (最近の JIT の変更からすると、かなり古くなっている可能性があります)。4.0 での CLR の変更に注意してください。 x86、x64、ia64 はそれを尊重します。 .