为什么尾调用优化不在这里?

时间:2016-12-31 02:16:58

标签: c# recursion factorization tail-call-optimization

我们正在使用递归来查找因子并且正在接收StackOverflow异常。我们已经阅读了the C# compiler on x64 computers performs tail call optimizations

  

JIT在运行优化代码而不是调试时肯定会做尾巴。

在我们的计划中,正在运行dotnet --configuration release

...                      
7214 is a factor of 1234567890
7606 is a factor of 1234567890
10821 is a factor of 1234567890
11409 is a factor of 1234567890                

Process is terminated due to StackOverflowException.

为什么没有发生尾调用优化?

class Program
{
    static void Main(string[] args)
    {
        const long firstCandidate = 1;
        WriteAllFactors(1234567890, firstCandidate);
    }

    private static void WriteAllFactors(long number, long candidate)
    {
        if (number % candidate == 0)
        {
            System.Console.WriteLine($"{candidate} is a factor of {number}");
        }

        candidate = candidate + 1;
        if(candidate > number / 2)
        {
            return;
        }

        WriteAllFactors(number, candidate);
    }
}

1 个答案:

答案 0 :(得分:3)

VSadov在回复中提供了明确的理由:

  

通常JIT在发现有利可图时会发出尾调用。

此外,他接着说:

  

这是C#中无法表达的部分。与内联不同,其中   可以强制通过属性,尾随当前不能被强制。   如果需要编写EmitMethodCall发出的代码,他   不能使用C#。

所以答案是,虽然可以使用和使用尾部调用,但无法预测何时使用它们或强制它们在C#中使用。