Performance 如果F#函数使用TailCall.net操作码,是否可以将其视为尾部递归函数
由于.net具有操作码, 这能用来判断F#函数是否真的是尾部递归的吗 如果是真的,是否有人制作了识别尾部和非尾部函数的VS加载项?有关F#团队如何编译尾部调用的摘要,请参阅F#团队博客 总之,Performance 如果F#函数使用TailCall.net操作码,是否可以将其视为尾部递归函数,performance,f#,tail-recursion,tail-call-optimization,Performance,F#,Tail Recursion,Tail Call Optimization,由于.net具有操作码, 这能用来判断F#函数是否真的是尾部递归的吗 如果是真的,是否有人制作了识别尾部和非尾部函数的VS加载项?有关F#团队如何编译尾部调用的摘要,请参阅F#团队博客 总之, 直接递归尾部调用通常转换为循环 相互递归和间接非递归尾部调用通常会转换为.NET尾部调用 但是,请参阅全文以了解所有血淋淋的细节。是的,如果编译器发出tailcall指令,则该调用将是tail recursive(从CLR 4开始,但仍有一些例外,它实际上不是tail recursive)。但这并不一定意
但是,请参阅全文以了解所有血淋淋的细节。是的,如果编译器发出
tail
call指令,则该调用将是tail recursive(从CLR 4开始,但仍有一些例外,它实际上不是tail recursive)。但这并不一定意味着整个函数都是尾部递归的。例如,我可以想象编译的QuickSort函数,第一个递归调用不是尾部递归调用,第二个是尾部递归调用
此外,仅仅因为某些函数不包含tail
指令,并不一定意味着它不是tail递归的。JIT编译器甚至可以在没有tail
指令的情况下识别tail调用,并对其进行优化
此外,F#编译器有时以非递归方式编译递归函数。这与正常的尾部调用优化有所不同,并且未使用
tail
指令,但是总体效果是相似的。在某些情况下,F#编译器会将一些递归情况转换为类似于goto
的情况,而无需使用.tail
指令-检测到这一点可能是错误的difficult@Brain:你是在问我是否想知道函数什么时候是尾部递归的吗?如果是这样的话,这将帮助我编写更高效的代码。这就像是即时反馈,如果我把某些东西优化为尾部递归,然后通过一个错误的更改使其无尾部递归。这样想吧。生产中的代码是尾部递归的,只做了一点修改,现在就不是尾部递归了。它投入生产后,突然开始进行堆栈溢出。你从来没有看到它的到来。回答很好,看看帖子。最后,它说:“我希望这些信息能有所帮助。我的下一篇文章将介绍如何克服本文中的一些限制。”你知道下一篇文章在哪里吗?@GuyCoder-好问题。当我们开始做更多的类型提供程序工作时,它被放在了次要位置,但我会努力完成它。你能在下一篇文章中谈论这个吗?