上次CLR中的尾调用优化



我(偶然)发现最后一个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仍然是经过优化的。为什么?

在递归调用Foo之后,您没有做任何有副作用的事情。我想你尝试了注释掉的代码,它确实阻止了优化。那么问题出在哪里呢?

你也可以写信给一个类成员,这将是一个不能丢弃的副作用。

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

然后在CCD_ 3结束时读取CCD_。

最新更新