Reputation: 1493
Let us say we have a method we would like it to return the same last result, if none of its parameters have changed from the last invocation. How should we go about checking its parameters have not changed? Cache the parameters in an object? array? for later check.
Compute( p1:boolean, p2:number, p3:number) {
// if any of p1 or p2 or p3 have changed from last invocation
// then redo computation
// else return last result.
}
In the past when dealing with a single parameter I have used a field like p1_last and compare to it on entry. something like this
if (p1 == this.p1_last) {
return this.result
}
else {
this.p1_last = p1 // save p1 for next invocation.
result = ....some algo....
return this.result
}
Your thoughts and suggested appreciated. Thank you.
Upvotes: 0
Views: 50
Reputation: 2201
You can create a general function that memorizes the inputs for a function passed.
function memorize<F extends (...args: any) => any>(func: F): F {
const cache = new Map()
return function (this: unknown, ...args: unknown[]): unknown {
// update the key calculation according to type of args
const argsKey = args.toString()
const cacheValue = cache.get(argsKey)
if (cacheValue) console.log('cache working')
if (cacheValue) return cacheValue
const result = func.apply(this, args)
cache.set(argsKey, result)
return result
} as F
}
let compute = function (p1: boolean, p2: number, p3: number) {
// sample computation
if (p1) return p2 * p3
return p2 + p3
}
compute = memorize(compute)
let x = compute(true, 1, 2)
console.log(x)
x = compute(true, 1, 2) // cached
console.log(x)
x = compute(false, 1, 2)
console.log(x)
x = compute(false, 1, 2) // cached
console.log(x)
x = compute(false, 3, 2)
console.log(x)
x = compute(false, 3, 2) // cached
console.log(x)
x = compute(true, 1, 2) // cached
console.log(x)
Upvotes: 2
Reputation: 1493
How about
private ComputeLastParams = {}
private ResultLast
Compute( p1:boolean, p2:number, p3:number) {
if ( ObjectEqual ( {p1, p2, p3}, this.ComputeLastParams )
) {
return this.ResultLast
}
//
this.ResultLast = /* some computation */
this.ComputeLastParams = {p1, p2, p3}
return this.ResultLast
}
static ObjectEqual(object1, object2) {
const keys1 = Object.keys(object1);
const keys2 = Object.keys(object2);
if (keys1.length !== keys2.length) {
return false;
}
for (let key of keys1) {
if (object1[key] !== object2[key]) {
return false;
}
}
return true;
}
Upvotes: 0
Reputation: 371069
If the number of parameters is fixed, it should be trivial to check against an array:
let lastParams: [boolean, number, number];
let lastResult; // type this properly...
function Compute( p1:boolean, p2:number, p3:number) {
if (
lastParams &&
lastParams[0] === p1 &&
lastParams[1] === p2 &&
lastParams[2] === p3
) {
return lastResult;
}
lastResult = /* some computation */
lastParams = [p1, p2, p3];
return lastResult;
}
Upvotes: 3