91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用Java實現算法為什么慎用遞歸

發布時間:2021-11-24 13:38:57 來源:億速云 閱讀:312 作者:柒染 欄目:編程語言

本篇文章為大家展示了使用Java實現算法為什么慎用遞歸,內容簡明扼要并且容易理解,絕對能使你眼前一亮,通過這篇文章的詳細介紹希望你能有所收獲。

現象 :

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

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

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

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

輸入參數:N

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

兩種實現代碼如下:

Java代碼

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線程棧的結構。java將為每個線程維護一個堆棧,堆棧里將為每個方法保存一個棧幀,棧幀代表了一個方法的運行狀態。 也就是我們常說的方法棧。***一個為當前運行的棧幀。

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

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

2.保存當前方法的棧幀狀態

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

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

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

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

上述內容就是使用Java實現算法為什么慎用遞歸,你們學到知識或技能了嗎?如果還想學到更多技能或者豐富自己的知識儲備,歡迎關注億速云行業資訊頻道。

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

阿荣旗| 佛山市| 舞阳县| 苏州市| 芜湖县| 平遥县| 台湾省| 青铜峡市| 得荣县| 乐昌市| 白城市| 广德县| 抚顺县| 六盘水市| 平潭县| 罗甸县| 习水县| 桦南县| 沾化县| 仁布县| 安塞县| 页游| 东丰县| 柳州市| 禹州市| 廉江市| 沙坪坝区| 内江市| 淮南市| 灵寿县| 那坡县| 建宁县| 周口市| 白山市| 长治市| 吉木乃县| 普安县| 昌都县| 宜川县| 枞阳县| 台江县|