在 Javascript 中,有没有办法缓存以下函数的结果:
- 一种)。计算成本高。
- 乙)。多次调用。
以经常调用的递归阶乘函数为例。通常我会创建一个单独的数组,例如facotrialResults = [];
当我计算它们时将我的结果添加到它们,factorialResults[x] = result;
但是,有没有更好的方法来完成这种缓存而不使用向全局命名空间添加新变量?
在 Javascript 中,有没有办法缓存以下函数的结果:
以经常调用的递归阶乘函数为例。通常我会创建一个单独的数组,例如facotrialResults = [];
当我计算它们时将我的结果添加到它们,factorialResults[x] = result;
但是,有没有更好的方法来完成这种缓存而不使用向全局命名空间添加新变量?
您可以将哈希附加到要缓存的函数。
var expensive_fn = function(val) {
var result = arguments.callee.cache[val];
if(result == null || result == undefined) {
//do the work and set result=...
arguments.callee.cache[val]=result;
}
return result;
}
expensive_fn.cache = {};
这将要求该函数是一个没有副作用的 1-1 函数。
您可以定义自己的函数属性,以便缓存结果与函数相关联,而不是在新数组中填充全局命名空间:
function factorial(n) {
if (n > 0) {
if (!(n in factorial)) // Check if we already have the result cached.
factorial[n] = n * factorial(n-1);
return factorial[n];
}
return NaN;
}
factorial[1] = 1; // Cache the base case.
唯一的问题是检查结果是否已缓存的开销。但是,如果检查的复杂性远低于重新计算问题,那么它是非常值得的。
使用缓存
这是一般的解决方案
// wrap cache function
var wrapCache = function(f, fKey){
fKey = fKey || function(id){ return id; };
var cache = {};
return function(key){
var _key = fKey(key);
if (!cache[_key]){
cache[_key] = f(key);
};
return cache[_key];
};
};
// functions that expensive
var getComputedRGB = function(n){
console.log("getComputedRGB called", n) ;
return n * n * n;
};
// wrapping expensive
var getComputedRGBCache = wrapCache(getComputedRGB, JSON.stringify);
console.log("normal call");
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
console.log(getComputedRGB(10));
// compute 4 times
console.log("cached call") ;
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
console.log(getComputedRGBCache(10));
// compute just 1 times
// output
=> normal call
getComputedRGB called 10
1000
getComputedRGB called 10
1000
getComputedRGB called 10
1000
getComputedRGB called 10
1000
=> cached call
getComputedRGB called 10
1000
1000
1000
1000