浅析Memoization
Memoization,简单的说就是优化计算机的性能,缓存那些重复性的函数操作和计算,使得第一次之后的调用可以直接从缓存中得到结果,而无需重新计算和运行复杂、费时的函数。这个跟Lazy Definition的原理是比较相似的,Lazy Definition主要是对函数进行重复定义,避免浏览器检测等恶心的事情。在javascript里实现Memoization的技术,Keith Gaughan做了相关的叙述:Memoization in JavaScript。特别是它对Fibonacci的优化让我特别的玩味。
对于Fibonacci普通的实现方式是:
//这个性能不咋的,函数调用太频繁了
function Fib(n) {
if (n < 2) { return n;}
return Fib(n - 1) + Fib(n - 2);
}
而Keith Gaughan对它的实现方式用Memoization进行了优化:
var IterMemoFib = function() {
var cache = [1, 1];
var fib = function(n) {
if (n >= cache.length) {
for (var i = cache.length; i <= n; i++) {
//这句代码很耐人寻味,还有循环的方式
cache[i] = cache[i - 2] + cache[i - 1];
}
}
return cache[n];
}
return fib;
}();
上面关于Fibonacci的优化,就是使用了Memoization技巧,将上一步的加法操作缓存起来,用户循环中下一轮的递增。缓存计算结果是Memorize应用最多的需求,避免了对计算结果的重复性计算,但是如果计算结果是动态的呢,或者说你想获取动态修改过后的计算结果呢? 比如DOM的length属性,这个是易变的,这个时候就不能去获取缓存的结果了,需要重复计算。