递归或迭代?
我喜欢递归。 我认为它可以简化很多事情。 另一个可能不同意; 我认为这也使代码更容易阅读。 但是,我注意到递归在C#等语言中的使用并不像LISP那样(顺便说一下,这是我最喜欢的语言,因为它是递归的)。
有谁知道是否有任何理由不使用C#等语言递归? 它比迭代更昂贵吗?
它们比迭代更昂贵吗?
对,他们是。 许多Lisp变体支持“尾部调用优化”的思想,它允许将递归函数调用的许多用途转换为迭代函数调用(这简化了一些)。 如果不支持tail-call,则递归函数调用将在堆栈上使用逐渐增加的内存。
它们比迭代更昂贵吗?
对,他们是。 递归需要创建一个新的堆栈框架以及一个调用和返回,而迭代通常只需要一个比较和分支,使其快得多; 然而,编译器可以对某些递归调用(即tail调用)执行tail-call优化,这样可以重新使用堆栈帧,从而使递归调用更为便宜,并有效地将它们转化为迭代。 方案实际上要求方案编译器实施尾部呼叫优化。
编译器和现代CPU的体系结构可以通过迭代进行大量优化,而这些优化无法用递归进行。 例如,处理器执行乐观计算的能力。 当处理器发现迭代空间时,它知道需要多长时间。 从一开始,在开始下一个循环之前不需要每次检查。 所以,他们在管理这些业务。 由于大多数CPU可以同时执行多个操作(通过流水线操作),因此可以在比递归更少的时间内解决迭代空间问题。 这甚至是尾部优化,因为CPU实际上一次处理大约4个循环(对于x4性能增益)。 这个增益将取决于CPU的架构。 这种架构很可能会成为收益的重要组成部分,下一代CPU将比这更进一步推动增长。
递归的真正问题是我们的硬件是基于VonNeumann的(图灵机可实现的变体),而不是Lisp机器,虽然有一些专门的Lisp硬件,但是你找不到它的任何桌面:)
链接地址: http://www.djcxy.com/p/80525.html下一篇: Simplest ways to cause stack overflow in C#, C++ and Java