JavaScript 記憶 Memoization

來源:互聯網
上載者:User

函數可以用對象去記住先前操作的結果,從而能避免無謂的運算,這種最佳化被稱為記憶(Memoization)。JavaScript 的對象和數組要實現這種最佳化是非常方便的

Memoization 是一種將函數傳回值緩衝起來的方法,在 Lisp, Ruby, Perl, Python 等語言中使用非常廣泛。隨著 Ajax 的興起,用戶端對伺服器的請求越來越密集(經典如 autocomplete),如果有一個良好的緩衝機制,那麼用戶端 JavaScript 程式的效率的提升是顯而易見的。

Memoization 原理非常簡單,就是把函數的每次執行結果都放入一個散列表中,在接下來的執行中,在散列表中尋找是否已經有相應執行過的值,如果有,直接返回該值,沒有才真正執行函數體的求值部分。很明顯,找值,尤其是在散列中找值,比執行函數快多了。現代 JavaScript 的開發也已經大量使用這種技術。

 

比如說,我們想要一個遞迴函式來計算 Fibonacci 數列。一個 Fibonacci 數字是之前兩個 Fibonacci 數字之和。最前面的兩個數字是 0 和 1。

var fibonacci = function (n) {    return n < 2 ? n : fibonacci(n - 1) + fibonacci(n - 2);};for (var i = 0; i <= 10; i += 1) {    document.writeln('// ' + i + ': ' + fibonacci(i));}// 0: 0// 1: 1// 2: 1// 3: 2// 4: 3// 5: 5// 6: 8// 7: 13// 8: 21// 9: 34// 10: 55

這樣是可以工作的,但是它做了很多無謂的工作。 Fibonacci 函數被調用了 453 次。我們調用了 11 次,而它自身調用了 442 次去計算可能已經被剛計算過的值。如果我們讓該函數具備記憶功能,就可以顯著地減少它的運算量。

我們在一個名為 memo 的數組裡儲存我們的儲存結果,儲存結果可以隱藏在閉包中。當我們的函數被調用時,這個函數首先看是否已經知道計算的結果,如果已經知道,就立即返回這個儲存結果。

var fibonacci = function() {    var memo = [0, 1];    var fib = function (n) {        var result = memo[n];        if (typeof result !== 'number') {            result = fib(n - 1) + fib(n - 2);            memo[n] = result;        }        return result;    };    return fib;}();

這個函數返回同樣的結果,但是它只被調用了 29 次。我們調用了它 11 次,它自身調用了 18 次去取得之前儲存的結果。

 

 

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.