3

我(偶然)发现最后一个 CLR 进行了尾调用优化。我已经用一段代码对其进行了测试,但坦率地说,它的行为并不符合我的预期。我认为当函数中的最后一件事是函数调用时,可能会发生尾调用优化。

我正在尝试“破坏”此代码以防止表单尾调用操作。

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 回答