现象 :

递归是我们很经典的一种算法实现,可以很好的描述一个算法的原理!对于算法的描述、表现和代码结构理解上,递归都是不错的选择!

但是本文想说的是java实现一个递归算法的时候尽量不要用递归实现,而是转换成的非递归实现。

最近在实现一个比较复杂算法的时候,尝试了一下,非递归实现相比递归实现速度上能提升1/3。

以下面一个简单的例子来说:(注:为了描述简单,所以这里只用一个简单的例子)

输入参数:N

输出结果:log1+log2+log3+....+logN

两种实现代码如下:

Java代码

packagetest;

publicclassRecursiveTest {

/**

* 递归实现

*

* @param n

* @return

*/

publicstaticdoublerecursive(longn) {

if(n ==1) {

returnMath.log(1);

}else{

returnMath.log(n) + recursive(n -1);

}

}

/**

* 非递归实现

*

* @param n

* @return

*/

publicstaticdoubledirectly(longn) {

doubleresult =0;

for(inti =1; i <= n; i++) {

result += Math.log(i);

}

returnresult;

}

publicstaticvoidmain(String[] args) {

inti =5000000;

longtest = System.nanoTime();

longstart1 = System.nanoTime();

doubler1 = recursive(i);

longend1 = System.nanoTime();

longstart2 = System.nanoTime();

doubler2 = directly(i);

longend2 = 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参数)和因为创建栈帧和切换的性能开销,最终大大的影响效率!

所以,如果你想提升你的算法效率,不要使用递归实现是一个基础原则!

另外,递归是我们用来理解算法的一个方法,当用代码来实现的时候基本都可以转换成非递归的代码实现!

java 什么时候用递归_如果要用Java实现算法,一定慎用递归相关推荐

  1. java寻找最大的字母_【LeetCode(Java) - 744】寻找比目标字母大的最小字母

    [LeetCode(Java) - 744]寻找比目标字母大的最小字母 [LeetCode(Java) - 744]寻找比目标字母大的最小字母 文章目录 1.题目描述 2.解题思路 3.解题代码 1. ...

  2. java国际化 英语的标识符_(转)Java 国际化

    1. Java国际化简介 Java既然作为一个跨平台的语言就必然要在各种不同的语言环境中使用, 为了解决这个问题Java给我们提供了一个工具类ResourceBundle, 帮助我们实现Java的国际 ...

  3. java人际对战五子棋_系统框图如下 java实现五子棋程序 可以实现人人对战 人机对战 简单功能 悔棋 认输...

    展开全部 一.实验题目 五子棋游戏e69da5e6ba9062616964757a686964616f31333365633835. 二.问题分析 五子棋是双人博弈棋类益智游戏,由围棋演变而来,属纯策 ...

  4. java编写代码用什么_如何学习用Java编写代码:为什么要学习以及从哪里开始

    java编写代码用什么 by John Selawsky 约翰·塞劳斯基(John Selawsky) 如何学习用Java编写代码:为什么要学习以及从哪里开始 (How to learn to cod ...

  5. java 著名的应用程序_即刻就业:java的应用程序有哪些

    通常我们一般使用java语言制作web开发,目前市场流行的电商网站等基本都是由java编写后台,著名JavaIDE也是Java写的,比如NetBeans,Eclipse,IDEA,JBuidler等. ...

  6. java 子线程传参_踩坑之Java执行Linux命令死锁阻塞挂起

    1 问题背景 最近在做一个需求需要调用linux下的某个脚本来对ai的模型进行训练,很简单的需求,我像往常一样写下如下的代码片段: Process process = Runtime.getRunti ...

  7. java比go难学_为什么Go比Java快这么多?看完这个例子就懂

    一,前言 本次小测试并不是试图说明Go是java的替代,Go lang和Java本就不是实现相同类型任务的语言 :Java是企业开发语言,而Go是系统编程语言.为什么Go比Java快这么多?看完这个例 ...

  8. java 工作3年水平_有着4年java工作经验,应该达到什么样的水平?

    四年Java工作经验已经不短了,应该要有比较高的技术水准. 1.集合 几乎是面试必问的内容,问的基本是底层实现原理,实现类的优缺点. 2.设计模式 23种设计模式中重点研究常用的十来种就可以了,面试中 ...

  9. 南邮java大作业实验报告_南京邮电大学java第三次实验报告

    实 验 报 告 ( 2017 / 2018学年 第2学期) 课程名称 JAVA语言程序设计 实验名称 Java集成开发环境的安装与使用. Java变量.表达式与控制结构 实验时间 2018 年 4 月 ...

  10. java获取环境变量路径_通过System获取java环境变量的路径

    通过System获取java环境变量的路径代码为: import java.io.FileNotFoundException; import java.io.FileOutputStream; imp ...

最新文章

  1. Sql server 2005带来的分页便利
  2. SAP 会计凭证和物料凭证的关系
  3. linux 编译 php7_Linux下编译安装PHP7
  4. Mac 10.12下安装python3环境
  5. ios7之后的一些更改
  6. Noark入门之极速体验
  7. 在Android开发中如何移除EditText上的输入焦点
  8. 共模电感适用的频率_详解消灭EMC的三大利器:电容器/电感/磁珠!
  9. 量子计算机可以预测未来吗,这台量子计算机可以同时预测16种不同的未来
  10. win11壁纸|windows11桌面壁纸
  11. SSD目标检测网络tensorRT推理【附代码】
  12. Linux命令之设置普通用户具有超级管理员权限sudo
  13. .net NPOI读写Doc文件
  14. 一元多项式加减法的C++实现
  15. 如何让实景三维倾斜摄影机载LiDAR三维激光扫描车点云数据顺畅服务于高速公路市政道路BIM改扩建正向三维可视化设计?高效建立精准地表三维模型DEM,让勘测与设计专业更直接地完成三维设计工作。
  16. RET RETF IRET IRETD 指令的不同
  17. 蓝桥七届 凑算式 JAVA
  18. 清除linux挖矿木马[crypto]的过程
  19. matlab安装方法以及在重复弹出mathwoks software activation界面的解决办法(需要的license.lic文件内容)
  20. 从Matlab实例学习遗传算法

热门文章

  1. 在Gradle 2.13中更好地处理“在插件Y上找不到属性X”
  2. 进阶– Java EE 7前端5强
  3. 书评– Kubernetes Up&Running,作者:Kelsey Hightower
  4. 存根类 测试代码 java_常规单元测试和存根–测​​试技术4
  5. Wildfly,Apache CXF和@SchemaValidation
  6. 使用FizzBu​​zz和JUnitParams进行单元测试
  7. Java终于可以加入字符串
  8. Spring MVC:资源
  9. java.util.concurrent.Future基础
  10. Java大新闻不断涌现:Java SE 6和OpenJDK