3

最後の CLR がテール コールの最適化を行うことを(偶然に)発見しました。コードでテストしましたが、率直に言って、期待どおりに動作しません。関数の最後のものが関数呼び出しである場合、末尾呼び出しの最適化が発生する可能性があると思いました。

フォーム テール コール op を防ぐために、このコードを「中断」しようとしています。

class Program
{
    static void Foo(int counter, int limit)
    {
        try
        {
            if (counter == limit)
            {
                return;
            }
            Foo(++counter, limit);

            int d = 1;
            d = Bar(d);
            //Console.Write(d);
            //Thread.Sleep(1);
            int baz = 0;
            var z = baz + d;
            StringBuilder b = new StringBuilder();
            b.Append("D");
        }
        catch (Exception)
        {
            throw;
        }
    }

    static int Sum(int s)
    {
        if (s == 1)
        {
            return s;
        }
        return s + Sum(s - 1);
    }

    static int Bar(int d)
    {
      return  d = 10 + d;
    }

    static void Main(string[] args)
    {
        int i = 0;

        Foo(i, 10000); // jitter 
        Sum(10000);

        Stopwatch stopwatch = new Stopwatch();
        stopwatch.Start();
        Foo(i, 10000);
        stopwatch.Stop();
        Console.WriteLine(string.Format("time of execution = {0}ms",stopwatch.ElapsedMilliseconds));

        stopwatch = new Stopwatch();
        stopwatch.Start();
        Sum(10000);
        stopwatch.Stop();
        Console.WriteLine(string.Format("time of execution = {0}ms", stopwatch.ElapsedMilliseconds));

        Console.ReadKey();
    }
}

それでも Foo は最適化されています。どうして?

4

1 に答える 1

0

への再帰呼び出しの後、副作用については何もしていませんFoo。コメントアウトされたコードを試したところ、最適化が妨げられたと思います。だから問題は何ですか?

クラスメンバーに書き込むこともできますが、これは破棄できない副作用になります。

private static int dummy;
static void Foo(int counter, int limit)
{
    if (counter == limit) return;
    Foo(++counter, limit);
    dummy++;
}

そしてdummy最後に読んでくださいMain

于 2011-06-24T00:30:57.313 に答える