繁体   English   中英

哪个更有效的递归或循环?

[英]Which is more efficient recursion or loops?

我很好奇哪个迭代效率更高。 我正在使用一个解析一个字符串解析为List。 递归更有效率CPU还是循环? 要么更高效的内存? 通过循环,我指的是,为每个,做,while,和任何其他类型。 这些循环中哪些更有效? 或者他们都是平等的? 只是好奇。

你不能就此作出一般性陈述。 这取决于循环的作用,编码方式以及JIT编译器如何优化它。 它也可以改变循环迭代的列表类型。 递归也是如此。

要获得可靠的答案,您需要根据具体情况检查各种备选方案,并(仔细!)对Java平台上的特定示例进行基准测试。

Java中的递归存在每个递归级别都需要堆栈帧的问题,并且Java堆栈具有有限的大小。 如果你必须过于递归,你的算法将因StackOverflowError而崩溃。 (当前一代Java平台不实现尾调用优化。)

您还希望避免在LinkedList进行基于索引的迭代(例如, for i = 0 to size - 1 ),因为这将给出O(N^2)行为。


幸运的是,不同类型的Java循环的性能差异通常不会产生足够的差异。 因此(以堆积深度问题为模,以及选择正确的List类的问题),您可以安全地将性能保持为“以后”...... 如果有必要进行性能优化, 则只处理它。

迭代通常会更有效率。 递归需要更多内存(设置堆栈帧)和时间(相同)。 但是,如果你可以设置尾递归,编译器几乎肯定会把它编译成迭代,或者编译成类似的东西,给你递归的可读性优势,具有迭代方法的性能。

在某些情况下,迭代解决方案将通过基本维护您自己的堆栈来实现,因此差异可能很小。

请参阅递归比循环更快? 更多细节。

那么根据我的说法,你问题的最佳答案是“它取决于”:

平均而言,在搜索SORTED集合时递归速度要快得多,因为您可以使用“Divide and Conquer”等算法(在这种情况下,将集合分为两部分,并将元素的一半发送到递归的下一步) 。当元素被找到或未包含在集合中时,递归停止。

但是对于大多数情况下,循环比递归更有效,因为简单的事实是,在不同的递归级别中,CPU会将变量保留在堆栈中,这基本上会填充它。 循环仅在堆栈中使用恒定数量的空间(通常,但例外情况适用)。 例如,如果您使用递归算法计算Fibbonacci序列,则需要数年时间才能在Fibonnacci(30)之后得到结果。 可以使用Memoization(基本上使用循环)计算该序列。

要记住的一件事是,递归更容易理解,并且比循环更容易解决问题。 许多基于循环的问题解决方案都是从循环算法(Memoization)中优化的递归算法(Divide and Conquer)开始的。 我参加了这个课程的课程,这真的很有趣。

希望我帮忙。

问候。

某些情况更适合递归......而其他情况则适用于简单迭代。 例如,导航目录优于递归。 其他树结构也是如此。 但是递归会占用更多内存。 对于迭代简单列表(如字符串),迭代(循环)更有效。

在我的选项中,循环更好,递归将具有函数调用跟踪,这将占用更多的内存。 而且它取决于功能

我同意其他海报,因为它确实取决于你正在解决的问题。 我个人的偏好通常是避免递归,因为与迭代相比,它可能更难维护和可能调试,并且取决于实现者或维护者的技能(无论哪个是较弱的链接)。 然而,未提及的一个项目是,使用一些新的Java线程功能(例如ForkJoinPool),递归解决方案可以非常容易地变成多线程解决方案。 并非Java中的线程化很困难,但如果在线程中分配工作负载成为问题并且这种类型的功能很有用,那么在设计系统时需要考虑这一点。

我创建了两个微基准测试来测量递归与循环性能。 他们都对随机数据集进行计算以避免JIT作弊。

在第一种情况下,我计算随机整数矩阵中的单元格的总和。 矩阵的一边等于60递归比循环慢10倍。

在第二种情况下,我通过生成Fibonacci数来比较递归与递归仿真。 递归仿真是GC友好的 - 计算期间没有内存分配。 在这种情况下,递归在“较小”情况下快2倍,在繁重计算下快5倍。

所以底线是Java中的递归非常有效,尽管作为循环不是很有效。

Environment:
OS: Windows 8 6.2, Core i5
JVM: Oracle Corporation Java HotSpot(TM) 64-Bit Server VM 23.25-b01

来源于github

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM