js遞歸性能優化

JavaScript 遞歸性能優化

遞歸是編程中強大的技術,但在 JavaScript 中如果不注意優化可能會導致性能問題甚至棧溢出。以下是幾種優化遞歸性能的方法:

1. 尾調用優化 (Tail Call Optimization, TCO)

ES6 引入了尾調用優化,但只在嚴格模式下有效:

'use strict';// 普通遞歸
function factorial(n) {if (n === 1) return 1;return n * factorial(n - 1); // 不是尾調用
}// 尾遞歸優化版本
function factorial(n, total = 1) {if (n === 1) return total;return factorial(n - 1, n * total); // 尾調用
}

注意:目前主流瀏覽器引擎對 TCO 的支持有限,Node.js 中需要開啟特定 flag。

2. 使用循環替代遞歸

// 遞歸版
function fibonacci(n) {if (n <= 1) return n;return fibonacci(n - 1) + fibonacci(n - 2);
}// 循環版(性能更好)
function fibonacci(n) {let a = 0, b = 1, temp;for (let i = 0; i < n; i++) {temp = a;a = b;b = temp + b;}return a;
}

3. 記憶化 (Memoization)

緩存已計算的結果避免重復計算:

function memoizedFibonacci() {const cache = {};return function fib(n) {if (n in cache) return cache[n];if (n <= 1) return n;cache[n] = fib(n - 1) + fib(n - 2);return cache[n];};
}const fib = memoizedFibonacci();

4. 使用 trampoline 技術

將遞歸轉換為循環執行:

function trampoline(fn) {return function(...args) {let result = fn(...args);while (typeof result === 'function') {result = result();}return result;};
}// 使用
const factorial = trampoline(function myself(n, acc = 1) {if (n <= 1) return acc;return () => myself(n - 1, n * acc);
});

5. 限制遞歸深度

function limitedRecursion(fn, maxDepth = 1000) {return function(...args) {if (--maxDepth < 0) throw new Error('Maximum call stack exceeded');return fn(...args);};
}

6. 使用異步遞歸

將遞歸調用拆分為多個事件循環:

function asyncRecursion(n, callback) {if (n <= 0) return process.nextTick(() => callback(1));process.nextTick(() => {asyncRecursion(n - 1, (result) => {callback(n * result);});});
}

最佳實踐建議

  1. 優先考慮尾遞歸形式
  2. 對于深度遞歸考慮使用循環
  3. 對于重復計算使用記憶化
  4. 對于非常深的遞歸考慮 trampoline 或異步方式
  5. 始終設置遞歸終止條件

記住,遞歸雖然優雅,但在 JavaScript 中并不總是最高效的解決方案。根據具體場景選擇最適合的方法。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/912189.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/912189.shtml
英文地址,請注明出處:http://en.pswp.cn/news/912189.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

vue界面增加自定義水印 js

vue整個界面增加自定義水印 需求&#xff1a;領導想要增加自定義水印 好不容易調完&#xff0c;還是想記錄一下,在.vue界面編寫 export default {mounted() {this.$nextTick(() > {this.addWatermark()})},methods: {// 關鍵&#xff1a;添加水印// 動態添加水印addWaterm…

Go開發工程師-Golang基礎知識篇

開篇 我們嘗試從2個方面來進行介紹&#xff1a; 1. 社招實際面試問題 2. 問題涉及的基礎點梳理 社招面試題 米哈游 1. Go 里面使用 Map 時應注意問題和數據結構 2. Map 擴容是怎么做的&#xff1f; 3. Map 的 panic 能被 recover 掉嗎&#xff1f;了解 panic 和 recover …

能否僅用兩臺服務器實現集群的高可用性??

我們將問題分為兩部分來回答&#xff1a;一是使用 Redis 或 Hazelcast 確保數據一致性后是否仍需 Oracle 或 MySQL 等數據庫&#xff1b;二是能否僅用兩臺服務器實現集群的高可用性。以下是詳細探討&#xff1a; 1. 使用 Redis 或 Hazelcast 確保數據一致性后&#xff0c;還需要…

spring-ai-alibaba DashScopeCloudStore自動裝配問題

問題 在學習spring-ai-alibaba時&#xff0c;發現1.0.0.2版本在自動裝配DashScopeCloudStore時&#xff0c;會報如下錯誤&#xff1a; Field dashScopeCloudStore in com.example.spring_ai_alibaba_examples.examples.SpringAiAlibabaExample01 required a bean of type com…

docker-compose部署nacos

1、docker-compose內容 高版本的nacos使用docker啟動&#xff0c;需要將所有的端口放開&#xff0c;僅僅開放8848端口&#xff0c;spring-boot客戶端獲取nacos配置的時候&#xff0c;可能取到的內容為空。 version: 3# 定義自定義網絡&#xff0c;確保服務間通信和外部訪問 ne…

CSRF 與 SSRF 的關聯與區別

CSRF 與 SSRF 的關聯與區別 區別 特性CSRF (跨站請求偽造)SSRF (服務器端請求偽造)攻擊方向客戶端 → 目標網站服務器 → 內部/外部資源攻擊目標利用用戶身份執行非預期操作利用服務器訪問內部資源或發起對外請求受害者已認證的用戶存在漏洞的服務器利用條件用戶必須已登錄目…

Payload-SDK自動升級

Payload-SDK自動升級 前言 自動升級旨在通過無人機更新負載上的軟件&#xff0c;包括不限于&#xff1a;Payload-SDK應用、配置文件等。對于文件的傳輸&#xff0c;大疆的Payload-SDK給我們提供了兩種方式&#xff1a;使用FTP協議和使用大疆自研的DCFTP。我們實現的自動升級是…

第五代移動通信新型調制及非正交多址傳輸技術研究與設計

第五代移動通信新型調制及非正交多址傳輸技術研究與設計 一、新型調制技術研究與實現 1. FBMC (濾波器組多載波) 調制實現 import numpy as np import matplotlib.pyplot as plt from scipy.fft import fft, ifft, fftshift from scipy.signal import get_window

AI 智能運維,重塑大型企業軟件運維:從自動化到智能化的進階實踐?

一、引言&#xff1a;企業軟件運維的智能化轉型浪潮? 在數字化轉型加速的背景下&#xff0c;大型企業軟件架構日益復雜&#xff0c;微服務、多云環境、分布式系統的普及導致傳統運維模式面臨效率瓶頸。AI 技術的滲透催生了智能運維&#xff08;AIOps&#xff09;的落地&#x…

Apache CXF安裝詳細教程(Windows)

本章教程,主要介紹,如何在Windows上安裝Apache CXF,JDK版本是使用的1.8. 一、下載Apache CXF Apache CXF(Apache Celtix Fireworks)是一個開源的 Web 服務框架,用于 構建和開發服務端與客戶端的 Web 服務應用程序。它支持多種 Web 服務標準,尤其是 SOAP(基于 XML 的協議…

逆向入門(22)程序逆向篇-TraceMe

界面看起來很普通 也沒有殼&#xff0c;直接搜索字符串找到關鍵代碼處 但是發現這些都是賦值&#xff0c;并沒有實現跳轉相關的函數。這里通過給彈窗函數下斷點&#xff0c;追一下返回函數來找觸發點。 再次點擊check&#xff0c;觸發斷點&#xff0c;接著按ctrlF9返回到函數…

中文PDF解析準確率排名

市面上的文檔解析工具種類各異&#xff0c;包括更適用于論文解析的&#xff0c;專精于表格數據提取的&#xff0c;針對手寫體優化的&#xff0c;適用于技術文檔的&#xff0c;擅長處理復雜多語言混排文檔的&#xff0c;專門處理政府招標文檔表格的&#xff0c;以及擅長金融類表…

Conformal LEC:官方學習教程

相關閱讀 Conformal LEChttps://blog.csdn.net/weixin_45791458/category_12993839.html?spm1001.2014.3001.5482 本文是對Conformal Equivalence Checking User Guide中附錄實驗的翻譯&#xff08;有刪改&#xff09;&#xff0c;實驗文件可見安裝目錄Conformal/share/cfm/l…

【Torch】nn.Embedding算法詳解

1. 定義 nn.Embedding 是 PyTorch 中的 查表式嵌入層&#xff08;lookup‐table&#xff09;&#xff0c;用于將離散的整數索引&#xff08;如詞 ID、實體 ID、離散特征類別等&#xff09;映射到一個連續的、可訓練的低維向量空間。它通過維護一個形狀為 (num_embeddings, emb…

cdq 三維偏序應用 / P4169 [Violet] 天使玩偶/SJY擺棋子

最近學了 cdq 分治想來做做這道題&#xff0c;結果被有些毒瘤的代碼惡心到了。 /ll 題目大意&#xff1a;一開始給定一些平面中的點。然后給定一些修改和詢問&#xff1a; 修改&#xff1a;增加一個點。詢問&#xff1a;給定一個點&#xff0c;求離這個點最近&#xff08;定義…

System.Threading.Tasks 庫簡介

System.Threading.Tasks 是 .NET 中任務并行庫(Task Parallel Library, TPL)的核心組件&#xff0c;它提供了基于任務的異步編程模型&#xff0c;是現代 .NET 并發編程的基礎。 設計原理 1. 核心目標 抽象并發工作&#xff1a;將并發操作抽象為"任務"概念 資源高效…

Python爬蟲實戰:研究jieba相關技術

1. 引言 1.1 研究背景與意義 隨著互聯網技術的飛速發展,網絡新聞已成為人們獲取信息的主要渠道之一。每天產生的新聞文本數據量呈爆炸式增長,如何從海量文本中高效提取有價值的信息,成為信息科學領域的重要研究課題。文本分析技術通過對文本內容的結構化處理和語義挖掘,能…

github 淘金技巧

1. 效率&#xff0c;搜索&#xff0c;先不管。后面再說。 2. 分享的話&#xff0c; 其實使用默認的分享功能也行。也是后面再說。此 app &#xff0c; 今天先做到這里。 下面我們再聊點其他東西。其實我還想問&#xff0c;這個事情&#xff0c;其他人是否也做了&#xff0c; ht…

RAG技術發展綜述

摘要 檢索增強生成&#xff08;Retrieval-Augmented Generation, RAG&#xff09;技術已成為大語言模型應用的核心技術棧。RAG有效解決了LLM的幻覺問題、知識截止和實時更新挑戰&#xff0c;目前正處于全面產業化階段。本文系統性地分析RAG的全棧技術架構&#xff0c;包括檢索…

集群聊天服務器---muduo庫(3)

使用muduo網絡庫進行編譯和鏈接的示例 項目的目錄結構 bin: 存放可執行文件。 lib: 存放庫文件。 include: 存放頭文件。 src: 存放源代碼文件。 build: 存放編譯生成的中間文件。 example: 存放示例代碼。 thirdparty: 存放第三方庫。 CMakeLists.txt: CMake構建系統…