Last active
December 28, 2016 17:52
-
-
Save zertosh/1486c709fa7683c7bf1e165f114d2875 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* 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