C#编译与尾递归优化?
基于stackoverflow的丰富的财富,我一直在关于是否尾递归优化是专门为c#代码做的答案。
Based on the rich wealth of stackoverflow, I've been getting on and off answers on whether the tail recursive optimization is done to specifically c# code. A few of the questions appeared to talk about
- 在发布的.net新版本中推测优化
- 将应用程序构建为x64bit应用程序以实现优化
- 在Visual Studio中从调试版本切换到发布版本以实现优化
- 根本没有优化,微软社区声称他们不会为安全问题执行尾递归优化(真的不理解这一点)。
- Speculation of the optimization in newer versions of .net that were being released
- Building application as a x64bit application to achieve the optimization
- Switching from a debug build to a release build in Visual Studio to achieve the optimization
- No optimization at all and that the microsoft community had claimed that they wouldn't do tail recursive optimization for "security issues" (didn't really understand this one)
- It happens by random
因此C#4.0(Visual Studio 2013/2015)如何确保尾递归优化if
So as of C# 4.0 (Visual Studio 2013/2015) how does one ensure the tail recursive optimization if one can ensure it at all?
有可以支持尾调用优化的不同级别。 JIT真正负责许多优化发生。 C#编译器本身甚至不做方法内联,这是JIT编译器的责任。 C#编译器可以使用 Tailcall IL操作码指定一个调用作为尾调用,但我相信没有版本的C#编译器这样做。 JIT编译器允许在看到合适的时候进行尾调用优化。特别是,我相信只有64位的JIT这样做。本博文介绍了一些方案其中JIT64不能使用尾调用优化。我确定标准可能会改变,因为他们正在改写JIT编译器,代号为RyuJIT。
There are different levels at which the tail call optimization can be supported. The JIT is really responsible for a lot of the optimizations that happen. The C# compiler itself doesn't even do method inlining, that is the JIT compiler's responsibility. The C# compiler could use the Tailcall IL opcode designating a call as a tail call, however I believe no version of C# compiler does this. The JIT compiler is permitted to make tail call optimizations whenever it see fit. In particular, I believe only the 64-bit JIT does this. This blog post outlines a number of scenarios in which JIT64 cannot use tail call optimization. I'm sure the criteria may be subject to change since they are working on a rewrite of the JIT compiler, codenamed RyuJIT.
如果你想要一个简单的程序示例可以使用TCO尝试:
If you want a short example of program that can use TCO try this:
class Program
{
static void Main(string[] args)
{
Test(1);
}
private static void Test(int i)
{
Console.WriteLine(i);
Test(i + 1);
}
}
设置项目以构建Release / x64 w / o喜欢32位),并在没有连接调试器的情况下启动。程序将永远运行。如果我不做所有这些事情,那么我在20947附近得到一个stackoverflow异常。
Set the project to build Release/x64 (or AnyCPU w/o prefer 32-bit) and start without the debugger attached. The program will run forever. If I do not do all of those things, then I get a stackoverflow exception around 20947.