本文主要用于回顾复习和加深理解
- 首先,递归思想在实现函数功能上十分方便,但是却十分耗费性能,比如下面这个例子
// 递归求阶乘
function jieCheng_1(num) {
if (num <= 1) {
return 1; // 递归的出口
}
return num * jieCheng_1(num - 1); // 递归
}
-
由递归的写法可发现,当num > 2时,计算出num的阶乘值所需要调用阶乘函数的次数为 : 本次调用一次 + 计算num-1的阶乘值所需要调用阶乘函数的次数
-
所以,我们可以设计一个缓存空间,用来将算出来的阶乘值保存起来,比如我们算出来了num-1的阶乘,就将它保存到缓存空间,当计算num的阶乘时,只需要从缓存中读取num-1的阶乘值,并和num相乘即为计算结果
// 递归求阶乘
var cache = {}; // 缓存区
function jieCheng_2(num) {
var cacheItem = cache[num];
if (cacheItem) {
return cacheItem;
} else {
return cache[num] = num <= 1 ? 1 : num * cache[num - 1];
}
}
- 我们继续优化,可以将缓存做成一个功能,利用闭包将缓存空间私有化
/* 缓存函数 */
function memory(fn) {
var cache = {}; // 私有化缓存结构
return function () {
var key = arguments[0],
cacheItem = cache[key];
if (cacheItem) {
return cacheItem;
} else {
return cache[key] = fn.apply(this, arguments);
}
}
}
-
我们比较下列三个函数在同等数量级的运行效率
- jieCheng_1
- jieCheng_2
- memoryJieCheng
console.time(); jieCheng_1(10000); console.timeEnd(); console.time(); jieCheng_2(10000); console.timeEnd(); console.time(); memory(jieCheng_1)(10000); console.timeEnd();
- 但注意: 闭包会造成内存泄露(占用), 时间成本和空间成本需权衡