成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

如果要用Java實現算法,一定慎用遞歸

開發(fā) 后端 算法
遞歸是我們很經典的一種算法實現,可以很好的描述一個算法的原理!對于算法的描述、表現和代碼結構理解上,遞歸都是不錯的選擇!

現象 :

遞歸是我們很經典的一種算法實現,可以很好的描述一個算法的原理!對于算法的描述、表現和代碼結構理解上,遞歸都是不錯的選擇!

但是本文想說的是java實現一個遞歸算法的時候盡量不要用遞歸實現,而是轉換成的非遞歸實現。

最近在實現一個比較復雜算法的時候,嘗試了一下,非遞歸實現相比遞歸實現速度上能提升1/3。

以下面一個簡單的例子來說:(注:為了描述簡單,所以這里只用一個簡單的例子)

輸入參數:N

輸出結果: log1+log2+log3+....+logN

兩種實現代碼如下:

Java代碼

  1. package test;     
  2.     
  3. public class RecursiveTest {     
  4.     /**    
  5.      * 遞歸實現    
  6.      *     
  7.      * @param n    
  8.      * @return    
  9.      */    
  10.     public static double recursive(long n) {     
  11.         if (n == 1) {     
  12.             return Math.log(1);     
  13.         } else {     
  14.             return Math.log(n) + recursive(n - 1);     
  15.         }     
  16.     }     
  17.     
  18.     /**    
  19.      * 非遞歸實現    
  20.      *     
  21.      * @param n    
  22.      * @return    
  23.      */    
  24.     public static double directly(long n) {     
  25.         double result = 0;     
  26.         for (int i = 1; i <= n; i++) {     
  27.             result += Math.log(i);     
  28.         }     
  29.         return result;     
  30.     }     
  31.     
  32.     public static void main(String[] args) {     
  33.         int i = 5000000;     
  34.         long test = System.nanoTime();     
  35.         long start1 = System.nanoTime();     
  36.         double r1 = recursive(i);     
  37.         long end1 = System.nanoTime();     
  38.         long start2 = System.nanoTime();     
  39.         double r2 = directly(i);     
  40.         long end2 = System.nanoTime();     
  41.     
  42.         System.out.println("recursive result:" + r1);     
  43.         System.out.println("recursive time used:" + (end1 - start1));     
  44.         System.out.println("non-recursive result:" + r2);     
  45.         System.out.println("non-recursive time used:" + (end2 - start2));     
  46.     }     
  47. }    

 

得到運行結果如下:

 

  1. recursive result:7.212475098340103E7  
  2. recursive time used:539457109   
  3. non-recursive result:7.212475098340103E7  
  4. non-recursive time used:282479757  

 

可以看出遞歸的運行時間是非遞歸運行時間將近2倍。

(注:以上代碼還是在-Xss200m的參數下運行的,如果棧空間不足,直接不能運行)

原因簡單分析:

 

 

上圖是java線程棧的結構。java將為每個線程維護一個堆棧,堆棧里將為每個方法保存一個棧幀,棧幀代表了一個方法的運行狀態(tài)。 也就是我們常說的方法棧。***一個為當前運行的棧幀。

那么每一次方法調用會涉及:

1.為新調用方法的生成一個棧幀

2.保存當前方法的棧幀狀態(tài)

3.棧幀上下文切換,切換到***的方法棧幀。

遞歸實現將導致在棧內存的消耗(往往需要調整Xss參數)和因為創(chuàng)建棧幀和切換的性能開銷,最終大大的影響效率!

所以,如果你想提升你的算法效率,不要使用遞歸實現是一個基礎原則!

另外,遞歸是我們用來理解算法的一個方法,當用代碼來實現的時候基本都可以轉換成非遞歸的代碼實現!

【編輯推薦】

  1. JavaOne 2009第三天:微軟與Sun/Oracle攜手并進
  2. 開發(fā)高可移植性J2ME的軟件
  3. Java虛擬機(JVM)中的內存設置詳解
  4. Java中的堆內存與棧內存分配淺析
  5. 非常全面的實用JavaScript開發(fā)工具列表
責任編輯:金賀 來源: ITEYE博客
相關推薦

2022-08-31 22:50:13

JavaScript函數JSON

2020-08-30 14:31:40

Python編程語言開發(fā)

2021-01-14 10:38:41

Java枚舉工具

2015-06-17 11:18:01

WiFi

2015-03-30 10:48:17

大數據大數據處理Hadoop

2019-01-21 08:20:17

通信4G5G

2013-09-03 09:09:30

大數據

2021-02-26 09:04:22

數組ArrayListHashMap

2017-09-28 08:35:35

前端HTML標簽大全

2022-02-18 12:24:39

PythonNumpy Arra大數據

2018-08-24 09:02:26

2021-06-01 20:38:04

Vuex對象import

2022-12-26 09:16:45

Guava架構模型

2015-03-17 15:18:02

私有云公共云數據中心

2022-11-16 11:55:22

網絡連接命令

2016-11-28 11:19:48

術語神秘

2019-11-12 08:53:00

線上命令日志

2022-08-26 08:17:32

Webshiro關系

2021-01-19 11:00:14

CPU核心單核

2022-08-01 07:07:41

TCP協(xié)議后端
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 91精品久久久久久久久久入口 | 国产亚洲精品精品国产亚洲综合 | 一区二区在线不卡 | 男人天堂网址 | 久久人体 | 91精品久久 | 一区二区三区四区五区在线视频 | 久久久激情 | 久久婷婷国产麻豆91 | 日日夜夜精品免费视频 | 天堂亚洲网 | 亚洲综合婷婷 | 亚洲a视频 | av男人的天堂av | 国产精品美女一区二区 | 成人精品鲁一区一区二区 | 午夜影院在线视频 | 成人精品免费 | 欧美天堂 | 国产电影一区 | 麻豆精品久久 | 99国产精品久久久久老师 | 中文字幕国产精品 | 伊人久久国产 | 精品一区二区三区四区五区 | 亚洲国产欧美在线 | 成人午夜视频在线观看 | 不用播放器看的av | 久久99久久 | 久久草在线视频 | 特黄特黄a级毛片免费专区 av网站免费在线观看 | 九九九久久国产免费 | 亚洲一区国产精品 | 亚洲精品99久久久久久 | h在线免费观看 | 天天爱av | 一区二区在线看 | 亚洲成人精品国产 | 免费三级网站 | 日韩精品一区二区三区久久 | 特级黄一级播放 |