- 浏览: 375095 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
真的全站唯一:
描述的能不能准确一点,我也以为bigDecimal性能比dou ...
【性能】Java BigDecimal和double性能比较 -
zhanggang807:
学习到了。。以后会考虑往这方面设计
【java规范】Java spi机制浅谈 -
Xiong506:
xiyuan1025 写道你这是在linux下吗,我在linu ...
[监控]Btrace监控简单笔记 -
Xiong506:
xiyuan1025 写道你这是在linux下吗,我在linu ...
[监控]Btrace监控简单笔记 -
Bll:
找不到实现类
【java规范】Java spi机制浅谈
现象 :
递归是我们很经典的一种算法实现,可以很好的描述一个算法的原理!对于算法的描述、表现和代码结构理解上,递归都是不错的选择!
但是本文想说的是java实现一个递归算法的时候尽量不要用递归实现,而是转换成的非递归实现。
最近在实现一个比较复杂算法的时候,尝试了一下,非递归实现相比递归实现速度上能提升1/3。
以下面一个简单的例子来说:
(注:为了描述简单,所以这里只用一个简单的例子。这个例子可以用更简单的数学公式来实现,所以请大家不要过分在意。 重点是想说明递归可能带来的一些问题)
输入参数:N
输出结果: log1+log2+log3+....+logN
两种实现代码如下:
package test; public class RecursiveTest { /** * 递归实现 * * @param n * @return */ public static double recursive(long n) { if (n == 1) { return Math.log(1); } else { return Math.log(n) + recursive(n - 1); } } /** * 非递归实现 * * @param n * @return */ public static double directly(long n) { double result = 0; for (int i = 1; i <= n; i++) { result += Math.log(i); } return result; } public static void main(String[] args) { int i = 5000000; long test = System.nanoTime(); long start1 = System.nanoTime(); double r1 = recursive(i); long end1 = System.nanoTime(); long start2 = System.nanoTime(); double r2 = directly(i); long end2 = System.nanoTime(); System.out.println("recursive result:" + r1); System.out.println("recursive time used:" + (end1 - start1)); System.out.println("non-recursive result:" + r2); System.out.println("non-recursive time used:" + (end2 - start2)); } }
得到运行结果如下:
recursive result:7.212475098340103E7
recursive time used:539457109
non-recursive result:7.212475098340103E7
non-recursive time used:282479757
可以看出递归的运行时间是非递归运行时间将近2倍。
(注:以上代码还是在-Xss200m的参数下运行的,如果栈空间不足,直接不能运行)
原因简单分析:
上图是java线程栈的结构。java将为每个线程维护一个堆栈,堆栈里将为每个方法保存一个栈帧,栈帧代表了一个方法的运行状态。 也就是我们常说的方法栈。最后一个为当前运行的栈帧。
那么每一次方法调用会涉及:
1.为新调用方法的生成一个栈帧
2.保存当前方法的栈帧状态
3.栈帧上下文切换,切换到最新的方法栈帧。
递归实现将导致在栈内存的消耗(往往需要调整Xss参数)和因为创建栈帧和切换的性能开销,最终大大的影响效率!
所以,如果你想提升你的算法效率,不要使用递归实现是一个基础原则!
另外,递归是我们用来理解算法的一个方法,当用代码来实现的时候基本都可以转换成非递归的代码实现!
评论
向楼上所说递归是用来简单化来表达数据处理的思想
要是不用递归试试计算 f(n)=f(n-1)+f(n-2)+f(n-3)+f(n-4)+f(n-5)
不管是用非递归或推数学公式(上面公式已经要计算一元五次方程的解了),会非常复杂
五次方程没有根式解,
手工计算5个根有点累。
计算机计算起来比较容易。
可以考虑用演化计算,选择一个比较好的算子,很快就能算出最优解
for
for
for
......
结果以参数的形式传递,这样可以省去递归由于要保存栈信息而带来的开销。
如果要做一些可扩展的组件,递归是不可避免的.
不会递归可耻;滥用递归也可耻;不会正确的使用递归同样可耻。
但如果迭代次数过多的话,会影响性能
空间消耗代价
recursive result:7.212475098340103E7
recursive time used:312802755
non-recursive result:7.212475098340103E7
non-recursive time used:312842609
JDK 对尾递归还是会自己做优化的
向楼上所说递归是用来简单化来表达数据处理的思想
要是不用递归试试计算 f(n)=f(n-1)+f(n-2)+f(n-3)+f(n-4)+f(n-5)
不管是用非递归或推数学公式(上面公式已经要计算一元五次方程的解了),会非常复杂
你根本就不理解本帖子要说明什么! 只是想说明递归的开销!
例子不是最重要的,"除非疯子才一个一个算logx相加 ....... "这个大家都懂得,不要过分去在意这个。
向楼上所说递归是用来简单化来表达数据处理的思想
要是不用递归试试计算 f(n)=f(n-1)+f(n-2)+f(n-3)+f(n-4)+f(n-5)
不管是用非递归或推数学公式(上面公式已经要计算一元五次方程的解了),会非常复杂
五次方程没有根式解,
手工计算5个根有点累。
计算机计算起来比较容易。
你确定无解?只是无代数根式解
五次方程符合Galois群理论,就可以有解。。。。(x-a)(x-b)(x-c)(x-d)(x-e)=0 a,b,c,d,e都不相等,这个五次方,你说有解吗?
发表评论
-
Xml ResourceBundle简单实现
2012-04-17 21:45 4364ResourceBundle主要是用于和本地语言环境相关的一些 ... -
【maven】多子模块maven模板工程archetype创建过程
2012-04-02 20:55 17576最近项目里需要创建一 ... -
【java基础】如何设计java应用程序的平滑停止
2012-03-05 23:44 10925java应用程序退出的触发机制有: 1.自动结束:应用没有存 ... -
【java并发】juc Executor框架详解
2012-02-26 13:55 12375Executor 框架是 juc 里提供的线程池的实现。 ... -
【java并发】juc高级锁机制探讨
2012-02-23 00:52 8510最近在看一些j ... -
【java并发】基于JUC CAS原理,自己实现简单独占锁
2012-02-14 13:47 7766synchronized的基本原理回 ... -
[NoSQL]MongoDB初体验
2012-01-05 16:06 3926因为未来业务发展的一 ... -
【JVM】HotSpot JVM内存管理和GC策略总结
2011-12-13 22:05 15879JVM的相关知识是学习java ... -
32位机器下的一个java.lang.OutOfMemoryError错误分析
2011-10-17 11:19 2547昨天在本人windows机器( ... -
[监控]Btrace监控简单笔记
2011-09-09 10:57 4903前阵子看了公司网站的一个cache 命中率统计的btrace监 ... -
DBCP数据源配置项记录
2011-09-01 20:22 2934网站最近发生了数据库连接爆掉的问题。排查了下各个应用存在 ... -
【性能】Java BigDecimal和double性能比较
2011-08-28 20:06 14110我们知道 java 里面有个 BigDecimal ... -
【Spring】IOC容器并发条件下,可能发生死锁
2011-08-28 17:07 68331.背景 上周在生产环境应用启 ... -
JDK7 AIO 初体验
2011-08-17 19:20 2535JDK7 AIO初体验 JDK7已经releas ... -
java日志,需要知道的几件事(commons-logging,log4j,slf4j,logback)
2011-02-28 17:12 46237java日志,需要知道的几件事 如果对于comm ... -
JVM问题诊断常用命令:jinfo,jmap,jstack
2010-08-17 17:55 123951.jinfo 描述:输出给定 java ... -
java 浮点数为什么精度会丢失
2010-07-15 22:30 4839由于对float或double 的使用不当,可能会出现精度 ... -
一个枚举类的方法设计
2010-06-21 15:28 1648public enum ActionType { A ... -
java内部字符编码浅析
2010-06-07 21:43 6794java内部字符编码浅析 本周遇到一个 ... -
JDK反射之JDK动态proxy
2010-06-07 21:27 4063JDK动态代理 JDK 动态代理是 java 反射的一 ...
相关推荐
java递归算法,java递归算法,java递归算法
java 用递归实现字符串反转 java 用递归实现字符串反转
用java实现的经典递归算法.doc
Java递归算法构造JSON树形结构,Java递归算法构造JSON树形结构Java递归算法构造JSON树形结构
用Java实现递归算法,有人把递归比做成用字典查找一个词语的意思
快速选择非递归与递归算法实现
java实现的经典递归算法三例 十分的经典,可以学习一下
java编写的递归算法的经典事例。 代码很短,没有点基础理解起来还真有点难度。很有挑战性。 不是我写的。这里只是分享一下。 功能是实现全排列。
15个典型的递归算法的JAVA实现,求N的阶乘、欧几里德算法(求最大公约数)、斐波那契数列、汉诺塔问题、树的三种递归遍历方式、快速排序、折半查找、图的遍历、归并排序、八皇后问题(回溯、递归)、棋盘覆盖(分治,...
JAVA递归实现全排列算法,含实现源代码,如a、b、c、d的全排列为: abcd abdc acbd acdb adcb adbc bacd badc bcad bcda bdca bdac cbad cbda cabd cadb cdab cdba dbca dbac dcba dcab dacb dabc
Java二分查找递归算法
Java实现用递归算法和非递归算法求解斐波那契数列问题.docx
.net 递归算法.net 递归算法.net 递归算法.net 递归算法.net 递归算法.net 递归算法.net 递归算法.net 递归算法
本文对经典的堆排序非递归算法进行了详细的分析,并用JAVA实现。用过该问题的JAVA实现,可使学习者清晰的观测到解决该问题的全过程。
一个用JAVA编写的扫雷程序,原创! 可以输入界面的行列数和雷数,此程序的精髓在打开一个不是雷而且周围没有雷的格子时,用到了递归的思想。
分别用递归和非递归方法实现二分查找算法 的完整程序,indexof()返回的是循环实现的二分法查找,getindex()实现的是递归算法实现的二分法查找。
Java递归算法
java 数据结构 递归 八皇后 完美递归 java 数据结构 递归 八皇后 完美递归
Java实现二分查找的递归和非递归算法