为什么不.NET / C#优化尾调用递归? [英] Why doesn't .NET/C# optimize for tail-call recursion?

查看:157
本文介绍了为什么不.NET / C#优化尾调用递归?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现<一href="http://stackoverflow.com/questions/340762/which-languages-support-tail-recursion-optimization">this问题哪些语言优化尾递归。我想知道的是,为什么C#没有尾递归优化,尽可能?

有关具体情况,为什么不是这种方法优化成一个圈(VS2008 32位,如果该事项):

 私有静态无效美孚(int i)以
{
  如果(我== 1000000)
    返回;

  如果(I%100 == 0)
    Console.WriteLine(ⅰ);

  富第(i + 1);
}
 

解决方案

JIT编译是不是花太多时间在做编译阶段(因而拖慢短命的应用大大)对没有采取足够的分析之间保持微妙的平衡应用在长期使用标准的提前编译竞争

有趣的是,NGEN编译步骤都不能有针对性地为他们的优化更有侵略性,我怀疑这是因为他们根本不希望有错误的地方的行为是依赖于JIT和NGEN是否负责机器$ C $℃。

在CLR本身不支持尾调用优化的,但语言特定的编译器必须知道如何生成相关的<一个href="http://msdn.microsoft.com/en-us/library/system.reflection.emit.op$c$cs.tailcall%28VS.95%29.aspx">op$c$c和JIT必须愿意尊重它。 F#的FSC将生成相关的运算codeS(尽管对于一个简单的递归也可能只是直接把整个事情变成一个while循环)。 C#的CSC没有。

请参阅<一href="http://blogs.msdn.com/davbr/archive/2007/06/20/enter-leave-tailcall-hooks-part-2-tall-tales-of-tail-calls.aspx">this博客文章的一些细节(很可能已经过时鉴于最近JIT的变化) 请注意,对于4.0的CLR变化<一href="http://blogs.msdn.com/b/clr$c$cgeneration/archive/2009/05/11/tail-call-improvements-in-net-framework-4.aspx">the x86,x64和IA64会尊重它

I found this question about which languages optimize tail recursion. What I want to know is why C# doesn't optimize tail recursion, whenever possible?

For a concrete case, why isn't this method optimized into a loop (VS2008 32 bit, if that matters)?:

private static void Foo(int i)
{
  if (i == 1000000)
    return;

  if (i % 100 == 0)
    Console.WriteLine(i);

  Foo(i+1);
}

解决方案

JIT compilation is a tricky balancing act between not spending too much time doing the compilation phase (thus slowing down short lived applications considerably) vs not doing enough analysis to keep the application competitive in the long term with a standard Ahead of Time compilation.

Interestingly the ngen compilation steps are not targeted to being more aggressive in their optimizations, I suspect this is because they simply don't want to have bugs where the behaviour is dependent on whether the JIT or ngen was responsible for the machine code.

The CLR itself does support tail call optimization, but the language specific compiler must know how to generate the relevant opcode and the JIT must be willing to respect it. F#'s fsc will generate the relevant opcodes (though for a simple recursion it may just convert the whole thing into a while loop directly). C#'s csc does not.

See this blog post for some details (quite possibly now out of date given recent JIT changes) Note that the CLR changes for 4.0 the x86, x64 and ia64 will respect it

这篇关于为什么不.NET / C#优化尾调用递归?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆