module: speed up package.json parsing more
Move the logic from the previous commit to C++ land in order to avoid creating a new string when we know we won't parse it anyway. PR-URL: https://github.com/nodejs/node/pull/15767 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Colin Ihrig <cjihrig@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com>
This commit is contained in:
parent
fdbb6dd042
commit
0fdd88a374
@ -120,7 +120,7 @@ function readPackage(requestPath) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!/"main"/.test(json))
|
if (json === '')
|
||||||
return packageMainCache[requestPath] = undefined;
|
return packageMainCache[requestPath] = undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -25,6 +25,7 @@
|
|||||||
|
|
||||||
#include "req-wrap-inl.h"
|
#include "req-wrap-inl.h"
|
||||||
#include "string_bytes.h"
|
#include "string_bytes.h"
|
||||||
|
#include "string_search.h"
|
||||||
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
@ -466,8 +467,9 @@ void FillStatsArray(double* fields, const uv_stat_t* s) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Used to speed up module loading. Returns the contents of the file as
|
// 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
|
// a string or undefined when the file cannot be opened. Returns an empty
|
||||||
// comes from not creating Error objects on failure.
|
// string when the file does not contain the substring '"main"' because that
|
||||||
|
// is the property we care about.
|
||||||
static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
|
static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
|
||||||
Environment* env = Environment::GetCurrent(args);
|
Environment* env = Environment::GetCurrent(args);
|
||||||
uv_loop_t* loop = env->event_loop();
|
uv_loop_t* loop = env->event_loop();
|
||||||
@ -516,7 +518,7 @@ static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const size_t size = offset - start;
|
const size_t size = offset - start;
|
||||||
if (size == 0) {
|
if (size == 0 || size == SearchString(&chars[start], size, "\"main\"")) {
|
||||||
args.GetReturnValue().SetEmptyString();
|
args.GetReturnValue().SetEmptyString();
|
||||||
} else {
|
} else {
|
||||||
Local<String> chars_string =
|
Local<String> chars_string =
|
||||||
|
@ -638,6 +638,7 @@ size_t SearchString(const Char* haystack,
|
|||||||
size_t needle_length,
|
size_t needle_length,
|
||||||
size_t start_index,
|
size_t start_index,
|
||||||
bool is_forward) {
|
bool is_forward) {
|
||||||
|
if (haystack_length < needle_length) return haystack_length;
|
||||||
// To do a reverse search (lastIndexOf instead of indexOf) without redundant
|
// To do a reverse search (lastIndexOf instead of indexOf) without redundant
|
||||||
// code, create two vectors that are reversed views into the input strings.
|
// code, create two vectors that are reversed views into the input strings.
|
||||||
// For example, v_needle[0] would return the *last* character of the needle.
|
// For example, v_needle[0] would return the *last* character of the needle.
|
||||||
@ -646,7 +647,6 @@ size_t SearchString(const Char* haystack,
|
|||||||
needle, needle_length, is_forward);
|
needle, needle_length, is_forward);
|
||||||
Vector<const Char> v_haystack = Vector<const Char>(
|
Vector<const Char> v_haystack = Vector<const Char>(
|
||||||
haystack, haystack_length, is_forward);
|
haystack, haystack_length, is_forward);
|
||||||
CHECK(haystack_length >= needle_length);
|
|
||||||
size_t diff = haystack_length - needle_length;
|
size_t diff = haystack_length - needle_length;
|
||||||
size_t relative_start_index;
|
size_t relative_start_index;
|
||||||
if (is_forward) {
|
if (is_forward) {
|
||||||
@ -664,6 +664,15 @@ size_t SearchString(const Char* haystack,
|
|||||||
}
|
}
|
||||||
return is_forward ? pos : (haystack_length - needle_length - pos);
|
return is_forward ? pos : (haystack_length - needle_length - pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <size_t N>
|
||||||
|
size_t SearchString(const char* haystack, size_t haystack_length,
|
||||||
|
const char (&needle)[N]) {
|
||||||
|
return SearchString(
|
||||||
|
reinterpret_cast<const uint8_t*>(haystack), haystack_length,
|
||||||
|
reinterpret_cast<const uint8_t*>(needle), N - 1, 0, true);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace node
|
} // namespace node
|
||||||
|
|
||||||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||||
|
@ -2,8 +2,13 @@
|
|||||||
require('../common');
|
require('../common');
|
||||||
const fixtures = require('../common/fixtures');
|
const fixtures = require('../common/fixtures');
|
||||||
const { internalModuleReadFile } = process.binding('fs');
|
const { internalModuleReadFile } = process.binding('fs');
|
||||||
|
const { readFileSync } = require('fs');
|
||||||
const { strictEqual } = require('assert');
|
const { strictEqual } = require('assert');
|
||||||
|
|
||||||
strictEqual(internalModuleReadFile('nosuchfile'), undefined);
|
strictEqual(internalModuleReadFile('nosuchfile'), undefined);
|
||||||
strictEqual(internalModuleReadFile(fixtures.path('empty.txt')), '');
|
strictEqual(internalModuleReadFile(fixtures.path('empty.txt')), '');
|
||||||
strictEqual(internalModuleReadFile(fixtures.path('empty-with-bom.txt')), '');
|
strictEqual(internalModuleReadFile(fixtures.path('empty-with-bom.txt')), '');
|
||||||
|
{
|
||||||
|
const filename = fixtures.path('require-bin/package.json');
|
||||||
|
strictEqual(internalModuleReadFile(filename), readFileSync(filename, 'utf8'));
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user