Skip to content

Instantly share code, notes, and snippets.

@zertosh
Last active December 28, 2016 17:52
Show Gist options
  • Save zertosh/1486c709fa7683c7bf1e165f114d2875 to your computer and use it in GitHub Desktop.
Save zertosh/1486c709fa7683c7bf1e165f114d2875 to your computer and use it in GitHub Desktop.
/**
* Usage:
*
* node -r this_file.js module_to_load.js
*/
'use strict';
var path = require('path');
var Module = require('module').Module;
var _load = Module._load;
var entries = null;
var order = null;
module.exports = {
start: start,
stop: stop,
};
// When loading profile-require.js with "-r", start profiling immediately.
if (module.parent && module.parent.id === 'internal/preload') {
start();
}
function start() {
entries = {};
order = 0;
Module._load = profile_require_time;
process.once('exit', stop);
}
function stop() {
process.removeListener('exit', stop);
Module._load = _load;
console.log(format());
entries = null;
order = null;
}
function format() {
var data = [
['#', '[order]', 'module', 'time'],
];
var cwd = process.cwd();
var filenames = Object.keys(entries);
for (var i = 0; i < filenames.length; i++) {
var entry = entries[filenames[i]];
var name = path.relative(cwd, entry.filename)
.replace(/\/node_modules\//g, '/:::/');
data.push([
i,
entry.order,
entry.init.toFixed(2),
Array(entry.depth).join('-') + name,
]);
}
var formatted = table(data, {
align: ['r', 'l', 'r', 'l'],
stringLength: function(str) {
return str.length;
}
});
return formatted;
}
function profile_require_time(request, parent, isMain) {
// https://github.com/nodejs/node/blob/v4.1.1/lib/module.js#L276
if (request === 'internal/repl' || request === 'repl') {
return _load.call(Module, request, parent, isMain);
}
const _filename = Module._resolveFilename(request, parent);
// Skip cached modules
if (Module._cache[_filename]) {
return Module._cache[_filename].exports;
}
const entry = entries[_filename] = {
depth: 1,
single: 0, // require time w/o children
init: 0, // require time
total: 0, // require time + deferred require times
order: ++order,
filename: _filename,
deferred: parent ? parent.loaded : false,
};
const time = process.hrtime();
const _exports = _load.call(Module, request, parent, isMain);
const diff = process.hrtime(time);
// diff: [seconds, nanoseconds]
entry.single = entry.init = entry.total = diff[0] * 1e3 + diff[1] / 1e6;
const _module = Module._cache[_filename];
// Some modules do not want to be found.
if (_module == null) {
return _exports;
}
// Module load time w/o children. Roughly equals parse plus execute time.
for (var i = 0; i < _module.children.length; i++) {
var child = _module.children[i];
var childEntry = entries[child.filename];
if (childEntry && !childEntry.deferred) {
entry.single -= childEntry.init;
}
}
for (var ancestor = _module.parent; ancestor !== null; ancestor = ancestor.parent) {
var ancestorEntry = entries[ancestor.filename];
// Account for deferred require load times.
if (ancestorEntry && entry.deferred) {
ancestorEntry.total += entry.init;
}
entry.depth++;
}
return _exports;
}
// https://github.com/substack/text-table/blob/2f7f2ba/index.js
function table(rows_, opts) {
if (!opts) opts = {};
var hsep = opts.hsep === undefined ? ' ' : opts.hsep;
var align = opts.align || [];
var stringLength = opts.stringLength
|| function (s) { return String(s).length; };
var dotsizes = rows_.reduce(function (acc, row) {
row.forEach(function (c, ix) {
var m = /\.[^.]*$/.exec(c);
var n = m ? m.index + 1 : c.length;
if (!acc[ix] || n > acc[ix]) acc[ix] = n;
});
return acc;
}, []);
var rows = rows_.map(function (row) {
return row.map(function (c_, ix) {
var c = String(c_);
if (align[ix] === '.') {
var m = /\.[^.]*$/.exec(c);
var index = m ? m.index + 1 : c.length;
var size = dotsizes[ix] + (/\./.test(c) ? 1 : 2)
- (stringLength(c) - index);
return c + Array(size).join(' ');
}
else return c;
});
});
var sizes = rows.reduce(function (acc, row) {
row.forEach(function (c, ix) {
var n = stringLength(c);
if (!acc[ix] || n > acc[ix]) acc[ix] = n;
});
return acc;
}, []);
return rows.map(function (row) {
return row.map(function (c, ix) {
var n = (sizes[ix] - stringLength(c)) || 0;
var s = Array(Math.max(n + 1, 1)).join(' ');
if (align[ix] === 'r' || align[ix] === '.') {
return s + c;
}
if (align[ix] === 'c') {
return Array(Math.ceil(n / 2 + 1)).join(' ')
+ c + Array(Math.floor(n / 2 + 1)).join(' ');
}
return c + s;
}).join(hsep).replace(/\s+$/, '');
}).join('\n');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment