Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如果F#函数使用TailCall.net操作码,是否可以将其视为尾部递归函数_Performance_F#_Tail Recursion_Tail Call Optimization - Fatal编程技术网

Performance 如果F#函数使用TailCall.net操作码,是否可以将其视为尾部递归函数

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)。但这并不一定意

由于.net具有操作码, 这能用来判断F#函数是否真的是尾部递归的吗

如果是真的,是否有人制作了识别尾部和非尾部函数的VS加载项?

有关F#团队如何编译尾部调用的摘要,请参阅F#团队博客

总之,

  • 直接递归尾部调用通常转换为循环
  • 相互递归和间接非递归尾部调用通常会转换为.NET尾部调用

  • 但是,请参阅全文以了解所有血淋淋的细节。

    是的,如果编译器发出
    tail
    call指令,则该调用将是tail recursive(从CLR 4开始,但仍有一些例外,它实际上不是tail recursive)。但这并不一定意味着整个函数都是尾部递归的。例如,我可以想象编译的QuickSort函数,第一个递归调用不是尾部递归调用,第二个是尾部递归调用

    此外,仅仅因为某些函数不包含
    tail
    指令,并不一定意味着它不是tail递归的。JIT编译器甚至可以在没有
    tail
    指令的情况下识别tail调用,并对其进行优化


    此外,F#编译器有时以非递归方式编译递归函数。这与正常的尾部调用优化有所不同,并且未使用
    tail
    指令,但是总体效果是相似的。

    在某些情况下,F#编译器会将一些递归情况转换为类似于
    goto
    的情况,而无需使用
    .tail
    指令-检测到这一点可能是错误的difficult@Brain:你是在问我是否想知道函数什么时候是尾部递归的吗?如果是这样的话,这将帮助我编写更高效的代码。这就像是即时反馈,如果我把某些东西优化为尾部递归,然后通过一个错误的更改使其无尾部递归。这样想吧。生产中的代码是尾部递归的,只做了一点修改,现在就不是尾部递归了。它投入生产后,突然开始进行堆栈溢出。你从来没有看到它的到来。回答很好,看看帖子。最后,它说:“我希望这些信息能有所帮助。我的下一篇文章将介绍如何克服本文中的一些限制。”你知道下一篇文章在哪里吗?@GuyCoder-好问题。当我们开始做更多的类型提供程序工作时,它被放在了次要位置,但我会努力完成它。你能在下一篇文章中谈论这个吗?