Skip to content

Instantly share code, notes, and snippets.

@davidrapin
Last active January 20, 2025 09:09
Show Gist options
  • Select an option

  • Save davidrapin/4bed1171885d40186bb1 to your computer and use it in GitHub Desktop.

Select an option

Save davidrapin/4bed1171885d40186bb1 to your computer and use it in GitHub Desktop.
Wrap all functions of an Object for call info statistic (number of calls, sync time, promises time)
/**
* Usage:
* var dataServiceInfo = wrapForCallInfo(require('../services/data').prototype);
* process.on('exit', function() {
* dataServiceInfo.print('DataService');
* });
*
* @param {Object} toWrap an object (or its prototype) to wrap for call statistics gathering.
* @returns {{print:function, data:Object}}
*/
function wrapForCallInfo(toWrap) {
var callData = {};
Object.getOwnPropertyNames(toWrap).forEach(function(fnName) {
if (typeof toWrap[fnName] !== 'function' || fnName === 'constructor') {
return
}
callData[fnName] = {calls:0, syncTime:0, asyncTime:0};
var orgFunction = toWrap[fnName];
toWrap[fnName] = function() {
var start = Date.now(), result;
callData[fnName].calls++;
result = orgFunction.apply(this, arguments);
callData[fnName].syncTime += (Date.now() - start);
// time promises as 'async time'
if (result && typeof result.then === 'function') {
result = result.then(function(value) {
callData[fnName].asyncTime += (Date.now() - start);
return value;
})
}
return result;
};
});
return {
print:function(prefix, limit, printNoCalls) {
if (limit === undefined) { limit = 10 }
var fullCallInfo = [], info, printed = 0, usedMethods = 0, allCalls = 0;
Object.keys(callData).forEach(function(fnName) {
info = callData[fnName];
allCalls += info.calls;
if (info.calls > 0) { usedMethods++ }
fullCallInfo.push({
name: fnName,
calls: info.calls,
syncTime: info.syncTime,
asyncTime: info.asyncTime,
allTime: info.syncTime + info.asyncTime,
allTimeAverage: (info.syncTime + info.asyncTime)/info.calls
})
});
fullCallInfo.sort(function(a, b) { return b.allTimeAverage - a.allTimeAverage });
console.log(
(prefix || 'Call statistics') + ' (' + allCalls + ' calls. ' +
usedMethods + '/' + fullCallInfo.length +' methods used)'
);
fullCallInfo.forEach(function(info) {
if (info.calls === 0 && !printNoCalls) { return }
if (limit !== null && ++printed > limit) { return false }
console.log(printed + ') ' + info.name + ': ' +
info.calls + ' calls. ' +
'Sync:' + info.syncTime + 'ms (avg:' + Math.round(info.syncTime/info.calls) + 'ms). ' +
'ASync:' + info.asyncTime + 'ms (avg:' + Math.round(info.asyncTime/info.calls) + 'ms).'
);
});
console.log('')
},
data: callData
};
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment