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;
|
||||
}
|
||||
|
||||
if (!/"main"/.test(json))
|
||||
if (json === '')
|
||||
return packageMainCache[requestPath] = undefined;
|
||||
|
||||
try {
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
#include "req-wrap-inl.h"
|
||||
#include "string_bytes.h"
|
||||
#include "string_search.h"
|
||||
|
||||
#include <fcntl.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
|
||||
// a string or undefined when the file cannot be opened. The speedup
|
||||
// comes from not creating Error objects on failure.
|
||||
// a string or undefined when the file cannot be opened. Returns an empty
|
||||
// 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) {
|
||||
Environment* env = Environment::GetCurrent(args);
|
||||
uv_loop_t* loop = env->event_loop();
|
||||
@ -516,7 +518,7 @@ static void InternalModuleReadFile(const FunctionCallbackInfo<Value>& args) {
|
||||
}
|
||||
|
||||
const size_t size = offset - start;
|
||||
if (size == 0) {
|
||||
if (size == 0 || size == SearchString(&chars[start], size, "\"main\"")) {
|
||||
args.GetReturnValue().SetEmptyString();
|
||||
} else {
|
||||
Local<String> chars_string =
|
||||
|
@ -638,6 +638,7 @@ size_t SearchString(const Char* haystack,
|
||||
size_t needle_length,
|
||||
size_t start_index,
|
||||
bool is_forward) {
|
||||
if (haystack_length < needle_length) return haystack_length;
|
||||
// To do a reverse search (lastIndexOf instead of indexOf) without redundant
|
||||
// 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.
|
||||
@ -646,7 +647,6 @@ size_t SearchString(const Char* haystack,
|
||||
needle, needle_length, is_forward);
|
||||
Vector<const Char> v_haystack = Vector<const Char>(
|
||||
haystack, haystack_length, is_forward);
|
||||
CHECK(haystack_length >= needle_length);
|
||||
size_t diff = haystack_length - needle_length;
|
||||
size_t relative_start_index;
|
||||
if (is_forward) {
|
||||
@ -664,6 +664,15 @@ size_t SearchString(const Char* haystack,
|
||||
}
|
||||
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
|
||||
|
||||
#endif // defined(NODE_WANT_INTERNALS) && NODE_WANT_INTERNALS
|
||||
|
@ -2,8 +2,13 @@
|
||||
require('../common');
|
||||
const fixtures = require('../common/fixtures');
|
||||
const { internalModuleReadFile } = process.binding('fs');
|
||||
const { readFileSync } = require('fs');
|
||||
const { strictEqual } = require('assert');
|
||||
|
||||
strictEqual(internalModuleReadFile('nosuchfile'), undefined);
|
||||
strictEqual(internalModuleReadFile(fixtures.path('empty.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