我听说在服务器上运行递归代码会影响性能。这个陈述是多么真实,应该使用递归方法作为最后的手段?
答案 0 :(得分:5)
递归可能比等效的迭代解决方案消耗更多的内存,因为后者可以被优化以仅占用它严格需要的内存,但是递归将所有局部变量保存在堆栈上,因此占用的量比严格需要的多一些。这只是内存限制环境中的一个问题(这种情况并不罕见),也可能是非常深的递归(几十个递归分支最多占用几百个字节,不可测量影响服务器的内存占用量),所以“最后的手段”是一个过高的。
但是当分析显示足迹影响很大时,你可以肯定执行的一次优化重构是recursion removal - 这是几十年前学术文献中的热门话题,但通常不难做到手工(特别是如果你保留所有的方法,递归或其他方式,相当小,你应该;)。
答案 1 :(得分:4)
我听说在服务器上运行递归代码会影响性能。这是多么的真实 声明?的
确实,它会影响性能,就像创建变量,循环或执行其他任何事情一样。
如果递归代码很差或不受控制,它将以不受控制的while循环消耗系统资源。
并且应该使用递归方法作为最后的手段吗?
没有。它可以作为第一手段使用,很多时候编写递归函数会更容易。取决于你的技能。但要明确的是,递归并不是特别邪恶。
答案 2 :(得分:3)
要讨论性能,您必须讨论非常具体的方案。使用适当递归是好的。如果您使用不恰当,您可能会破坏堆栈,或者只是使用太多堆栈。如果你以某种方式获得一个递归的尾调而不会终止它(通常是一个错误,例如试图走一个循环图),尤其如此,因为它甚至不会打击堆栈(它只会永远运行,扼杀CPU个循环)。
但是要把它弄好(并将深度限制在理智的数量),这很好。
答案 3 :(得分:2)
编程错误的递归不会结束对机器产生负面影响,消耗了大量资源,并在最坏的情况下威胁整个系统的稳定性。
否则,递归是一个完全合法的工具,如循环和其他结构。它们对性能本身没有负面影响。
答案 4 :(得分:2)
答案 5 :(得分:1)
当您必须编写算法时,Recusion是一种可供选择的工具。当你必须处理像树或图这样的重复数据结构时,它也比迭代容易得多。如果(作为经验法则)你可以评估将回归深度评估为不太大的东西通常是无害的,只要你不忘记结束条件......
大多数现代编译器都能够优化某些类型的递归调用(在内部用非递归等价物替换它们)。使用 tail 递归非常简单,即递归调用是返回结果之前的最后一条指令。
然而,Java存在一些特定问题。底层JVM不提供任何类型的goto指令。这设置了编译器可以做的限制。如果它是一个函数内部的尾端递归,它可以被函数内部的一个简单循环所取代,但是如果终端调用是通过另一个函数完成的,或者如果多个函数反复调用另一个函数,那么它很难做到。定位JVM字节码。 SUN JVM不支持尾调用优化,但有plans要更改它,IBM JVM does支持尾调用优化。
对于某些语言(像LISP或Haskell这样的函数式语言),递归也是编写程序的唯一(或更自然)方式。在基于JVM的函数语言(如Clojure或Scala)上,缺少尾调用优化是一个导致Scala中trampolines之类的解决方法的问题。
答案 6 :(得分:0)
在服务器上运行任何代码都会影响性能。服务器性能通常会受到存储I / O的影响,所以在“服务器性能”水平上看到一般算法策略的问题很奇怪。
答案 7 :(得分:0)
深度递归可能导致堆栈溢出,这是令人讨厌的。要小心,如果你需要,很难再起床。小巧,易于管理的工作更易于处理和并行化。