mirror of
https://github.com/nodejs/node.git
synced 2024-12-01 16:10:02 +01:00
lib: speed up require(), phase 2
Replace calls to fs.readFileSync() with an internal variant that does not create Error objects on failure and is a bit speedier in general. A secondary benefit is that it improves start-up times in the debugger because it no longer emits thousands of exception debug events. On a medium-sized application[0], this commit and its predecessor reduce start-up times from about 1.5s to 0.5s and reduce the number of start-up exceptions from ~6100 to 32, half of them internal to the application. [0] https://github.com/strongloop/loopback-sample-app PR-URL: https://github.com/nodejs/io.js/pull/1801 Reviewed-By: Trevor Norris <trev.norris@gmail.com>
This commit is contained in:
parent
b14fd1a720
commit
1bbf8d0720
@ -6,6 +6,7 @@ const runInThisContext = require('vm').runInThisContext;
|
||||
const assert = require('assert').ok;
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
const internalModuleReadFile = process.binding('fs').internalModuleReadFile;
|
||||
const internalModuleStat = process.binding('fs').internalModuleStat;
|
||||
|
||||
|
||||
@ -65,10 +66,10 @@ function readPackage(requestPath) {
|
||||
return packageMainCache[requestPath];
|
||||
}
|
||||
|
||||
try {
|
||||
var jsonPath = path.resolve(requestPath, 'package.json');
|
||||
var json = fs.readFileSync(jsonPath, 'utf8');
|
||||
} catch (e) {
|
||||
var jsonPath = path.resolve(requestPath, 'package.json');
|
||||
var json = internalModuleReadFile(jsonPath);
|
||||
|
||||
if (json === undefined) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@
|
||||
# include <io.h>
|
||||
#endif
|
||||
|
||||
#include <vector>
|
||||
|
||||
namespace node {
|
||||
|
||||
using v8::Array;
|
||||
@ -433,6 +435,50 @@ Local<Value> BuildStatsObject(Environment* env, const uv_stat_t* s) {
|
||||
return handle_scope.Escape(stats);
|
||||
}
|
||||
|
||||
// Used to speed up module loading. Returns the contents of the file as
|
||||
// a string or undefined when the file cannot be opened. The speedup
|
||||
// comes from not creating Error objects on failure.
|
||||
static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
|
||||
CHECK(args[0]->IsString());
|
||||
node::Utf8Value path(env->isolate(), args[0]);
|
||||
|
||||
FILE* const stream = fopen(*path, "rb");
|
||||
if (stream == nullptr) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<char> chars;
|
||||
while (!ferror(stream)) {
|
||||
const size_t kBlockSize = 32 << 10;
|
||||
const size_t start = chars.size();
|
||||
chars.resize(start + kBlockSize);
|
||||
const size_t numchars = fread(&chars[start], 1, kBlockSize, stream);
|
||||
if (numchars < kBlockSize) {
|
||||
chars.resize(start + numchars);
|
||||
}
|
||||
if (numchars == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK_EQ(false, ferror(stream));
|
||||
CHECK_EQ(0, fclose(stream));
|
||||
|
||||
size_t start = 0;
|
||||
if (chars.size() >= 3 && 0 == memcmp(&chars[0], "\xEF\xBB\xBF", 3)) {
|
||||
start = 3; // Skip UTF-8 BOM.
|
||||
}
|
||||
|
||||
Local<String> chars_string =
|
||||
String::NewFromUtf8(env->isolate(),
|
||||
&chars[start],
|
||||
String::kNormalString,
|
||||
chars.size() - start);
|
||||
args.GetReturnValue().Set(chars_string);
|
||||
}
|
||||
|
||||
// Used to speed up module loading. Returns 0 if the path refers to
|
||||
// a file, 1 when it's a directory or < 0 on error (usually -ENOENT.)
|
||||
// The speedup comes from not creating thousands of Stat and Error objects.
|
||||
@ -1161,6 +1207,7 @@ void InitFs(Handle<Object> target,
|
||||
env->SetMethod(target, "rmdir", RMDir);
|
||||
env->SetMethod(target, "mkdir", MKDir);
|
||||
env->SetMethod(target, "readdir", ReadDir);
|
||||
env->SetMethod(target, "internalModuleReadFile", InternalModuleReadFile);
|
||||
env->SetMethod(target, "internalModuleStat", InternalModuleStat);
|
||||
env->SetMethod(target, "stat", Stat);
|
||||
env->SetMethod(target, "lstat", LStat);
|
||||
|
Loading…
Reference in New Issue
Block a user