Skip to content

Commit da6b66a

Browse files
committed
src: make InternalModuleReadJSON() linear again
Commits dcb6929, 4396beb and 8a96d05 turned the O(n) scan in InternalModuleReadJSON() into an O(4n) scan. Fix the performance regression by turning that into a linear scan again.
1 parent f4a4a1a commit da6b66a

File tree

1 file changed

+35
-9
lines changed

1 file changed

+35
-9
lines changed

src/node_file.cc

+35-9
Original file line numberDiff line numberDiff line change
@@ -829,20 +829,46 @@ static void InternalModuleReadJSON(const FunctionCallbackInfo<Value>& args) {
829829
}
830830

831831
const size_t size = offset - start;
832-
if (size == 0 || (
833-
size == SearchString(&chars[start], size, "\"name\"") &&
834-
size == SearchString(&chars[start], size, "\"main\"") &&
835-
size == SearchString(&chars[start], size, "\"exports\"") &&
836-
size == SearchString(&chars[start], size, "\"type\""))) {
837-
args.GetReturnValue().Set(env->empty_object_string());
838-
} else {
839-
Local<String> chars_string =
832+
char* p = &chars[start];
833+
char* pe = &chars[size];
834+
char* pos[2];
835+
char** ppos = &pos[0];
836+
837+
while (p < pe) {
838+
char c = *p++;
839+
if (c == '"') goto quote; // Keeps code flat and inner loop small.
840+
if (c == '\\' && p < pe && *p == '"') p++;
841+
continue;
842+
quote:
843+
*ppos++ = p;
844+
if (ppos < &pos[2]) continue;
845+
ppos = &pos[0];
846+
847+
char* s = &pos[0][0];
848+
char* se = &pos[1][-1]; // Exclude quote.
849+
size_t n = se - s;
850+
851+
if (n == 4) {
852+
if (0 == memcmp(s, "main", 4)) break;
853+
if (0 == memcmp(s, "name", 4)) break;
854+
if (0 == memcmp(s, "type", 4)) break;
855+
} else if (n == 7) {
856+
if (0 == memcmp(s, "exports", 7)) break;
857+
}
858+
}
859+
860+
Local<String> return_value;
861+
if (p < pe) {
862+
return_value =
840863
String::NewFromUtf8(isolate,
841864
&chars[start],
842865
v8::NewStringType::kNormal,
843866
size).ToLocalChecked();
844-
args.GetReturnValue().Set(chars_string);
867+
} else {
868+
return_value = env->empty_object_string();
845869
}
870+
871+
args.GetReturnValue().Set(return_value);
846872
}
847873

848874
// Used to speed up module loading. Returns 0 if the path refers to

0 commit comments

Comments
 (0)