【问题标题】:C# compilation with tail recursive optimization?带有尾递归优化的 C# 编译?
【发布时间】:2015-06-16 17:35:30
【问题描述】:

基于 stackoverflow 的丰富资源,我一直在断断续续地回答是否对特定的 c# 代码进行了尾递归优化。有几个问题似乎在谈论

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

那么从 C# 4.0 (Visual Studio 2013/2015) 开始,如果可以确保尾递归优化,如何确保它?

【问题讨论】:

  • 当您链接您遇到的其他问题和答案时,通常会为这些帖子增加很多价值,以便我们可以按照您的思路和路径来解决您的问题。
  • C#的当前版本是5,版本6在VS 2015预览版中可用。
  • @TravisJ 我打算尝试将其他问题联系起来,但不确定我是否能找到它们,因为我在很长一段时间内查看了它们。
  • Jon skeet 和 Scott Hanselman 在 2016 年进行的有用对话youtu.be/H2KkiRbDZyc?t=3302

标签: c# c#-4.0 recursion tail-recursion


【解决方案1】:

可以支持尾调用优化的不同级别。 JIT 真正负责任何 .NET 程序中的大多数优化。 C# 编译器本身甚至不进行方法内联,这是 JIT 编译器的职责。 C# 编译器可以使用Tailcall IL opcode 将调用指定为尾调用,但是我相信没有任何版本的 C# 编译器可以做到这一点。 JIT 编译器可以在它认为合适的时候进行尾调用优化。特别是,我相信只有 64 位 JIT 才能做到这一点。这个blog post 概述了 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(或 AnyCPU,不支持 32 位)并在不附加调试器的情况下启动。该程序将永远运行。如果我不做所有这些事情,那么我会在 20947 年左右得到一个 stackoverflow 异常。

【讨论】:

  • 第二个链接引用与第一个相同。你是这个意思吗? blogs.msdn.com/b/clrcodegeneration/archive/2009/05/11/…另外,好帖子:stackoverflow.com/questions/15864670/generate-tail-call-opcode
  • @Erti-ChrisEelmaa 修复了链接,您链接到的帖子中也引用了该链接。
  • 为了确保 JIT 编译器甚至有可能进行尾递归优化,请将其设置为 64 位构建?此外,是否可以添加任何直接的东西(关键字、属性标签)来增加优化的可能性?
  • @KiroYakuza - 您可以考虑通过存储方法调用来强制优化。
  • @KiroYakuza 它不一定需要是 x64 版本。它可以是 64 位平台上的任何 CPU(不喜欢 32 位)。您应该在没有附加调试器的情况下运行发布版本。我确实知道影响 JIT 是否认为方法适合 TCO 的任何属性。
猜你喜欢
  • 2010-09-07
  • 1970-01-01
  • 2021-05-30
  • 2012-10-14
  • 1970-01-01
  • 2014-06-23
  • 1970-01-01
相关资源
最近更新 更多