JavaScript Memoization

weixin_34262482發表於2009-08-06

轉自這裡

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

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

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"/> <title>JavaScript Memoization</title> <script type="text/javascript"> /** * JavaScript Momoization * @param {string} func name of function / method * @param {object} [obj] mothed's object or scope correction object * * MIT / BSD license */ function Memoize(func, obj){ var obj = obj || window, func = obj[func], cache = {}; return function(){ var key = Array.prototype.join.call(arguments, '_'); if (!(key in cache)) cache[key] = func.apply(obj, arguments); return cache[key]; } } var fib = { fib: function(n){ if (n == 0 || n == 1) return 1; return this.fib(n-1) + this.fib(n-2); }, fib_memo: function(n){ if (n == 0 || n == 1) return 1; return this.fib_memo(n-1) + this.fib_memo(n-2); } } fib.fib_memo = Memoize('fib_memo', fib); function get(id){ return document.getElementById(id); } function test(el, func, scope, arg){ if ('string' == typeof el) el = get(el); el.onclick = function(){ var start = (new Date()).getTime(); var result = func.call(scope, arg); var end = (new Date()).getTime(); this.nextSibling.innerHTML = '結果為 ' + result + ',耗時 ' + (end-start) + 'ms'; } } window.onload = function(){ test('fib', fib.fib, fib, 30); test('fib_memo', fib.fib_memo, fib, 30); } </script> </head> <body> <h1>JavaScript Memoization</h1> <h2>Snippets</h2> <pre class="brush:javascript;gutter:false;toolbar:false"> /** * JavaScript Momoization * @param {string} func name of function / method * @param {object} [obj] mothed's object or scope correction object * * MIT / BSD license */ function Memoize(func, obj){ var obj = obj || window, func = obj[func], cache = {}; return function(){ var key = Array.prototype.join.call(arguments, '_'); if (!(key in cache)) cache[key] = func.apply(obj, arguments); return cache[key]; } } var fib = { fib: function(n){ if (n == 0 || n == 1) return 1; return this.fib(n-1) + this.fib(n-2); }, fib_memo: function(n){ if (n == 0 || n == 1) return 1; return this.fib_memo(n-1) + this.fib_memo(n-2); } } fib.fib_memo = Memoize('fib_memo', fib); </pre> <p><button id="fib">測試 <code>fib.fib(30)</code></button><b></b></p> <p><button id="fib_memo">測試 <code>fib.fib_memo(30)</code></button><b></b></p> </body> </html>

執行程式碼

相關文章