I have node.JS app that have methods called multiple times with the same parameters. (optimization problem trying out combinations)
The source code is quite large and I'm not familiar with it and I'm trying to find what methods are called multiple times with the same parameters in order to memorize them and improve the performance of the algo.
So I'm trying to intercept all method calls with their respective parameters, store them in Set() and see the difference between the method calls and the unique parameters.
I'm using ES6 Proxy object like so:
process.log = {};
process.traceMethodCalls = function (obj) {
return new Proxy(obj, {
get(target, method, receiver) {
if (typeof process.log[method] === 'undefined') {
process.log[method] = { calls: 0, params: new Set() };
}
return function (...args) {
process.log[method].calls += 1;
process.log[method].params.add(JSON.stringify(args));
return target[method].apply(this, args);
};
}
});
}
Then I can review the log variable for difference in log.calls vs log.params.size() to see the best candidates for memorization.
This technique works great, but obviously does not intercept object literal calls to itself. Here is example where it fails (example module from the project):
module.exports = function (app) {
const fitness = {
staticFunction: () => true,
normalize: (a, b) => {
return (fitness.staticFunction()) ? a+b : 0;
}
};
return process.traceMethodCalls(fitness); // injected my proxy here
};
After execution I'll have the normalize function in my log variable, but not staticFunction since it wasn't called on the intercepted object but directly on fitness.
What will be the best way to intercept these method calls ?
You could inject your proxy like so:
let fitness = { … };
fitness = process.traceMethodCalls(fitness);
return fitness;
Alternatively, just don't use functions that refer to the original target. Instead, use this
:
const fitness = {
staticFunction() { return true },
normalize(a, b) {
return (this.staticFunction()) ? a+b : 0;
}
};