lib: speed up require(), phase 1

Replace calls to fs.statSync() with an internal variant that does not
create Error or Stat objects that put strain on the garbage collector.

A secondary benefit is that it improves start-up times in the debugger
because it no longer emits thousands of exception debug events.

PR-URL: https://github.com/nodejs/io.js/pull/1801
Reviewed-By: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
Ben Noordhuis 2015-05-26 13:23:26 +02:00
parent 98649fd31a
commit b14fd1a720
2 changed files with 35 additions and 20 deletions

View file

@ -6,6 +6,7 @@ const runInThisContext = require('vm').runInThisContext;
const assert = require('assert').ok;
const fs = require('fs');
const path = require('path');
const internalModuleStat = process.binding('fs').internalModuleStat;
// If obj.hasOwnProperty has been overridden, then calling
@ -56,13 +57,6 @@ const debug = Module._debug;
// -> a.<ext>
// -> a/index.<ext>
function statPath(path) {
try {
return fs.statSync(path);
} catch (ex) {}
return false;
}
// check if the directory is a package.json dir
const packageMainCache = {};
@ -94,7 +88,7 @@ function tryPackage(requestPath, exts) {
if (!pkg) return false;
var filename = path.resolve(requestPath, pkg);
return tryFile(filename, null) || tryExtensions(filename, exts) ||
return tryFile(filename) || tryExtensions(filename, exts) ||
tryExtensions(path.resolve(filename, 'index'), exts);
}
@ -104,18 +98,19 @@ function tryPackage(requestPath, exts) {
Module._realpathCache = {};
// check if the file exists and is not a directory
function tryFile(requestPath, stats) {
stats = stats || statPath(requestPath);
if (stats && !stats.isDirectory()) {
return fs.realpathSync(requestPath, Module._realpathCache);
}
return false;
function tryFile(requestPath) {
const rc = internalModuleStat(requestPath);
return rc === 0 && toRealPath(requestPath);
}
function toRealPath(requestPath) {
return fs.realpathSync(requestPath, Module._realpathCache);
}
// given a path check a the file exists with any of the set extensions
function tryExtensions(p, exts) {
for (var i = 0, EL = exts.length; i < EL; i++) {
var filename = tryFile(p + exts[i], null);
var filename = tryFile(p + exts[i]);
if (filename) {
return filename;
@ -150,11 +145,10 @@ Module._findPath = function(request, paths) {
var filename;
if (!trailingSlash) {
var stats = statPath(basePath);
// try to join the request to the path
filename = tryFile(basePath, stats);
if (!filename && stats && stats.isDirectory()) {
const rc = internalModuleStat(basePath);
if (rc === 0) { // File.
filename = toRealPath(basePath);
} else if (rc === 1) { // Directory.
filename = tryPackage(basePath, exts);
}