Skip to content

Commit 0c7cb79

Browse files
committed
Use a lookup table for whitespaces and comments
1 parent f34b28d commit 0c7cb79

File tree

1 file changed

+44
-39
lines changed

1 file changed

+44
-39
lines changed

ext/json/ext/parser/parser.c

Lines changed: 44 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -442,58 +442,63 @@ static void raise_parse_error(const char *format, const char *start)
442442
rb_enc_raise(enc_utf8, rb_path2class("JSON::ParserError"), format, ptr);
443443
}
444444

445-
static inline void
446-
json_eat_whitespace(JSON_ParserState *state) {
447-
while (state->cursor < state->end) {
448-
switch (*state->cursor) {
449-
case ' ':
450-
case '\t':
451-
case '\n':
452-
case '\r':
453-
state->cursor++;
454-
break;
445+
static const bool whitespace[256] = {
446+
[' '] = 1,
447+
['\t'] = 1,
448+
['\n'] = 1,
449+
['\r'] = 1,
450+
['/'] = 1,
451+
};
452+
453+
static void
454+
json_eat_comments(JSON_ParserState *state)
455+
{
456+
if (state->cursor + 1 < state->end) {
457+
switch(state->cursor[1]) {
455458
case '/': {
456-
if (state->cursor + 1 < state->end) {
457-
switch(state->cursor[1]) {
458-
case '/': {
459-
state->cursor = memchr(state->cursor, '\n', state->end - state->cursor);
460-
if (!state->cursor) {
461-
state->cursor = state->end;
462-
} else {
463-
state->cursor++;
464-
}
465-
break;
466-
}
467-
case '*': {
468-
state->cursor += 2;
469-
while (true) {
470-
state->cursor = memchr(state->cursor, '*', state->end - state->cursor);
471-
if (!state->cursor) {
472-
state->cursor = state->end;
473-
break;
474-
} else {
475-
state->cursor++;
476-
if (state->cursor < state->end && *state->cursor == '/') {
477-
state->cursor++;
478-
break;
479-
}
480-
}
481-
}
459+
state->cursor = memchr(state->cursor, '\n', state->end - state->cursor);
460+
if (!state->cursor) {
461+
state->cursor = state->end;
462+
} else {
463+
state->cursor++;
464+
}
465+
break;
466+
}
467+
case '*': {
468+
state->cursor += 2;
469+
while (true) {
470+
state->cursor = memchr(state->cursor, '*', state->end - state->cursor);
471+
if (!state->cursor) {
472+
state->cursor = state->end;
473+
break;
474+
} else {
475+
state->cursor++;
476+
if (state->cursor < state->end && *state->cursor == '/') {
477+
state->cursor++;
482478
break;
483479
}
484-
default:
485-
return;
486480
}
487481
}
488482
break;
489483
}
490-
491484
default:
492485
return;
493486
}
494487
}
495488
}
496489

490+
static inline void
491+
json_eat_whitespace(JSON_ParserState *state)
492+
{
493+
while (state->cursor < state->end && RB_UNLIKELY(whitespace[(unsigned char)*state->cursor])) {
494+
if (RB_LIKELY(*state->cursor != '/')) {
495+
state->cursor++;
496+
} else {
497+
json_eat_comments(state);
498+
}
499+
}
500+
}
501+
497502
static inline VALUE build_string(const char *start, const char *end, bool intern, bool symbolize)
498503
{
499504
if (symbolize) {

0 commit comments

Comments
 (0)