memoize
如果一个函数调用开销很大,我们就可能希望能把结果缓存下来,以便后续调用时直接获得结果。举个例子,计算阶乘就比较耗时:
'use strict';
function factorial(n) {
console.log('start calculate ' + n + '!…');
var s = 1, i = n;
while (i > 1) {
s = s * i;
i —;
}
console.log(n + '! = ' + s);
return s;
}
factorial(10); // 3628800
// 注意控制台输出:
// start calculate 10!…
// 10! = 3628800
用 memoize() 就可以自动缓存函数计算的结果:
'use strict';
var factorial = _.memoize(function(n) {
console.log('start calculate ' + n + '!…');
var s = 1, i = n;
while (i > 1) {
s = s * i;
i —;
}
console.log(n + '! = ' + s);
return s;
});
// 第一次调用:
factorial(10); // 3628800
// 注意控制台输出:
// start calculate 10!…
// 10! = 3628800
// 第二次调用:
factorial(10); // 3628800
// 控制台没有输出
对于相同的调用,比如连续两次调用 factorial(10) ,第二次调用并没有计算,而是直接返回上次计算后缓存的结果。不过,当你计算 factorial(9) 的时候,仍然会重新计算。
可以对 factorial() 进行改进,让其递归调用:
'use strict';
var factorial = _.memoize(function(n) {
console.log('start calculate ' + n + '!…');
if (n < 2) {
return 1;
}
return n * factorial(n - 1);
});
factorial(10); // 3628800
// 输出结果说明factorial(1)~factorial(10)都已经缓存了:
// start calculate 10!…
// start calculate 9!…
// start calculate 8!…
// start calculate 7!…
// start calculate 6!…
// start calculate 5!…
// start calculate 4!…
// start calculate 3!…
// start calculate 2!…
// start calculate 1!…
factorial(9); // 362880
// console无输出