使用尾递归优化进行C#编译?

13

基于stackoverflow丰富的资源,我已经对是否专门针对c#代码进行尾递归优化得到了答案。其中一些问题似乎涉及以下几点:

  1. 推测在新版本的.net中进行了优化
  2. 构建应用程序为x64位应用程序以实现优化
  3. 在Visual Studio中从调试生成切换到发布生成以实现优化
  4. 完全没有优化,微软社区声称他们不会为“安全问题”进行尾递归优化(对此不太理解)
  5. 优化是随机发生的

因此,在C#4.0(Visual Studio 2013/2015)中,如何确保尾递归优化,如果可以确保它,该怎么做?


3
当你在帖子中提供其他相关问题和答案的链接时,通常会为这些帖子增加很多价值,因为我们可以跟随你的思路和路径了解你提出问题的背景。请注意,不要改变原来的意思,使内容更加通俗易懂。 - Travis J
1
C#的当前版本是5,版本6可在VS 2015预览版中使用。 - Mike Zboray
@TravisJ 我本来想尝试链接其他问题,但不太确定能否追踪它们,因为我在相当长的时间内查看了它们。 - Bennett Yeo
2016年Jon Skeet和Scott Hanselman关于IT的有益对话https://youtu.be/H2KkiRbDZyc?t=3302 - Daniel B
1个回答

23

尾调用优化可以在不同的级别上得到支持。对于任何.NET程序,JIT都负责大部分优化工作。C#编译器本身甚至不会执行方法内联,这是JIT编译器的责任。C#编译器可以使用Tailcall IL操作码将调用指定为尾调用,但我认为没有任何版本的C#编译器这样做。只有64位JIT允许在其认为合适的情况下进行尾调用优化。特别地,我相信只有64位JIT才能这样做。这篇博客文章概述了许多情况下JIT64无法使用尾调用优化。我确信这些标准可能会因为他们正在重写JIT编译器(代号RyuJIT)而发生改变。

如果您想要一个可以使用TCO的简短示例程序,请尝试以下内容:

class Program
{
    static void Main(string[] args)
    {
        Test(1);
    }

    private static void Test(int i)
    {
        Console.WriteLine(i);
        Test(i + 1);
    }
}

将项目设置为构建“Release/x64”(或不使用32位优先的AnyCPU),并在未附加调试器的情况下启动。程序将永远运行。如果我没有完成所有这些操作,那么我会在大约20947左右遇到堆栈溢出异常。


1
第二个链接引用了第一个链接中的相同内容。你是不是想要这个链接?http://blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/tail-call-improvements-in-net-framework-4.aspx 另外,这篇文章也很好:https://dev59.com/uWUo5IYBdhLWcg3wpg7N - Erti-Chris Eelmaa
那么,为了确保JIT编译器进行尾递归优化的可能性,将其设置为64位构建?此外,是否有任何可以立即添加以增加优化概率的关键字或属性标签? - Bennett Yeo
1
@KiroYakuza - 你可以考虑通过存储方法调用来强制进行优化。 - Travis J
1
@KiroYakuza 不一定需要是x64构建,它可以是在64位平台上的任意CPU(不带prefer 32位). 您应该运行未附加调试器的发布构建。我不知道有任何属性会影响JIT是否认为方法适合TCO。 - Mike Zboray
@TravisJ,“存储方法调用”是什么意思? - Bennett Yeo
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接