关闭。这个问题是基于意见的。它目前不接受答案。
**想改进这个问题吗?**编辑这篇文章,更新这个问题,以便用事实和引文来回答。
昨天关门了。
改进这个问题
在线阅读之后,我发现java并没有优化尾部递归。那么,如果head和tail递归会产生相同的结果,那么使用它有什么意义呢。
此外,循环的性能总是比递归(尾部和头部)好;因为有时候不用考虑迭代就可以更容易地使用递归。请告诉我是否应该使用循环。
如果我错了,请纠正我,因为我刚刚开始递归。
关闭。这个问题是基于意见的。它目前不接受答案。
**想改进这个问题吗?**编辑这篇文章,更新这个问题,以便用事实和引文来回答。
昨天关门了。
改进这个问题
在线阅读之后,我发现java并没有优化尾部递归。那么,如果head和tail递归会产生相同的结果,那么使用它有什么意义呢。
此外,循环的性能总是比递归(尾部和头部)好;因为有时候不用考虑迭代就可以更容易地使用递归。请告诉我是否应该使用循环。
如果我错了,请纠正我,因为我刚刚开始递归。
1条答案
按热度按时间vsnjm48y1#
是的,java中任何递归算法的性能几乎总是比使用循环重写同一事物差得多。使用循环通常同样简单:
制作一个堆栈或deque对象。
创建一个表示所有相关状态的类。
编写一个循环,从堆栈或deque中获取内容并对其进行操作。
作为“操作it”的一部分,你可以自由地堆积新的工作——类似于给自己打电话。
这个“公式”应该适用于任何递归算法。
然而,您编写的绝大多数代码并不重要,性能方面也是如此。确切地说,如果你的应用程序对cpu有任何可测量的影响,那么你的应用程序使用的99%的cpu资源几乎总是被整个代码库的0.1%所使用。
很明显,我们的任务是[a]发现0.1%和[b]提高效率。
剩下的99.9%无关紧要。这不是一个“千刀万剐”的情况——这真的不重要。您可以将代码编写的效率降低10到100倍,即使您多次犯下这样的错误,只要它不在0.1%的关键路径上,您永远不会注意到,您的用户也不会注意到。
因此,从这个意义上讲,如果您认为使用递归编写代码更容易,阅读代码也更容易,那么请自作主张。只要知道,如果你的分析器告诉你这个递归算法在0.1%(关键路径)的范围内,是的,第一步:重写远离递归。
旁注:只要不递归太远,JVM就可以进行大量优化。有些虚拟机,比如azul,如果堆栈跟踪是重复的(递归算法有重复的堆栈跟踪),甚至会消除一堆堆栈跟踪。因此,即使是java中的递归算法,在性能方面也是很好的。要可靠地获得这个结果要困难得多,因为您现在依赖于在定制vm实现中进行的优化。