Skip to content

Commit 947902e

Browse files
committed
parser.c: Optimize json_parse_digits
We can use `ctz` builtin to get the number of consecutive digits. ``` == Parsing float parsing (2251051 bytes) ruby 3.4.6 (2025-09-16 revision dbd83256b1) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- after 25.000 i/100ms Calculating ------------------------------------- after 231.963 (± 0.0%) i/s (4.31 ms/i) - 1.175k in 5.065467s Comparison: before: 215.3 i/s after: 232.0 i/s - 1.08x faster ```
1 parent ded62a5 commit 947902e

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

ext/json/ext/parser/parser.c

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1101,13 +1101,20 @@ static inline int json_parse_digits(JSON_ParserState *state, uint64_t *accumulat
11011101
continue;
11021102
}
11031103

1104-
if ((match & 0xFFFFFFFF) == 0x33333333) { // 4 consecutive digits
1104+
size_t consecutive_digits = trailing_zeros64(match ^ 0x3333333333333333) / CHAR_BIT;
1105+
if (consecutive_digits >= 4) {
11051106
*accumulator = (*accumulator * 10000) + decode_4digits_unrolled((uint32_t)next_8bytes);
11061107
state->cursor += 4;
1107-
break;
1108+
consecutive_digits -= 4;
1109+
}
1110+
1111+
while (consecutive_digits) {
1112+
*accumulator = *accumulator * 10 + (*state->cursor - '0');
1113+
consecutive_digits--;
1114+
state->cursor++;
11081115
}
11091116

1110-
break;
1117+
return (int)(state->cursor - start);
11111118
}
11121119
#endif
11131120

0 commit comments

Comments
 (0)