summaryrefslogtreecommitdiff
path: root/ext/json/parser/parser.rl
diff options
context:
space:
mode:
authorJean Boussier <[email protected]>2024-11-13 13:34:27 +0100
committerHiroshi SHIBATA <[email protected]>2024-11-14 11:21:39 +0900
commita4183781ec2ed00585932575ce48e0c561dc6dc4 (patch)
treed0a8a3e355c4512870fd57f415636d34d5bcd8f6 /ext/json/parser/parser.rl
parent1bab8bf88fdd23d9a86131a43fac7736c88e4608 (diff)
[ruby/json] Only use the key cache if the Hash is in an Array
Otherwise the likeliness of seeing that key again is really low, and looking up the cache is just a waste. Before: ``` == Parsing small hash (65 bytes) ruby 3.4.0dev (2024-11-13T12:32:57Z fstr-update-callba.. https://github.com/ruby/json/commit/9b44b455b3) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- json 343.049k i/100ms oj 213.943k i/100ms Oj::Parser 31.583k i/100ms rapidjson 303.433k i/100ms Calculating ------------------------------------- json 3.704M (± 1.5%) i/s (270.01 ns/i) - 18.525M in 5.003078s oj 2.200M (± 1.1%) i/s (454.46 ns/i) - 11.125M in 5.056526s Oj::Parser 285.369k (± 4.8%) i/s (3.50 μs/i) - 1.453M in 5.103866s rapidjson 3.216M (± 1.6%) i/s (310.95 ns/i) - 16.082M in 5.001973s Comparison: json: 3703517.4 i/s rapidjson: 3215983.0 i/s - 1.15x slower oj: 2200417.1 i/s - 1.68x slower Oj::Parser: 285369.1 i/s - 12.98x slower == Parsing test from oj (258 bytes) ruby 3.4.0dev (2024-11-13T12:32:57Z fstr-update-callba.. https://github.com/ruby/json/commit/9b44b455b3) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- json 54.539k i/100ms oj 41.473k i/100ms Oj::Parser 24.064k i/100ms rapidjson 51.466k i/100ms Calculating ------------------------------------- json 549.386k (± 1.6%) i/s (1.82 μs/i) - 2.781M in 5.064316s oj 417.003k (± 1.3%) i/s (2.40 μs/i) - 2.115M in 5.073047s Oj::Parser 226.500k (± 4.7%) i/s (4.42 μs/i) - 1.131M in 5.005466s rapidjson 526.124k (± 1.0%) i/s (1.90 μs/i) - 2.676M in 5.087176s Comparison: json: 549385.6 i/s rapidjson: 526124.3 i/s - 1.04x slower oj: 417003.4 i/s - 1.32x slower Oj::Parser: 226500.4 i/s - 2.43x slower ``` After: ``` == Parsing small hash (65 bytes) ruby 3.4.0dev (2024-11-13T12:32:57Z fstr-update-callba.. https://github.com/ruby/json/commit/9b44b455b3) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- json 361.394k i/100ms oj 217.203k i/100ms Oj::Parser 28.855k i/100ms rapidjson 303.404k i/100ms Calculating ------------------------------------- json 3.859M (± 2.9%) i/s (259.13 ns/i) - 19.515M in 5.061302s oj 2.191M (± 1.6%) i/s (456.49 ns/i) - 11.077M in 5.058043s Oj::Parser 315.132k (± 7.1%) i/s (3.17 μs/i) - 1.587M in 5.065707s rapidjson 3.156M (± 4.0%) i/s (316.88 ns/i) - 15.777M in 5.008949s Comparison: json: 3859046.5 i/s rapidjson: 3155778.5 i/s - 1.22x slower oj: 2190616.0 i/s - 1.76x slower Oj::Parser: 315132.4 i/s - 12.25x slower == Parsing test from oj (258 bytes) ruby 3.4.0dev (2024-11-13T12:32:57Z fstr-update-callba.. https://github.com/ruby/json/commit/9b44b455b3) +YJIT +PRISM [arm64-darwin24] Warming up -------------------------------------- json 55.682k i/100ms oj 40.343k i/100ms Oj::Parser 25.119k i/100ms rapidjson 51.500k i/100ms Calculating ------------------------------------- json 555.808k (± 1.4%) i/s (1.80 μs/i) - 2.784M in 5.010092s oj 412.283k (± 1.7%) i/s (2.43 μs/i) - 2.098M in 5.089900s Oj::Parser 279.306k (±13.3%) i/s (3.58 μs/i) - 1.356M in 5.022079s rapidjson 517.177k (± 2.7%) i/s (1.93 μs/i) - 2.626M in 5.082352s Comparison: json: 555808.3 i/s rapidjson: 517177.1 i/s - 1.07x slower oj: 412283.2 i/s - 1.35x slower Oj::Parser: 279306.5 i/s - 1.99x slower ``` https://github.com/ruby/json/commit/00c45ddc9f
Diffstat (limited to 'ext/json/parser/parser.rl')
-rw-r--r--ext/json/parser/parser.rl7
1 files changed, 5 insertions, 2 deletions
diff --git a/ext/json/parser/parser.rl b/ext/json/parser/parser.rl
index 9a1f739233..eab60b919b 100644
--- a/ext/json/parser/parser.rl
+++ b/ext/json/parser/parser.rl
@@ -392,6 +392,7 @@ typedef struct JSON_ParserStruct {
VALUE decimal_class;
VALUE match_string;
FBuffer fbuffer;
+ int in_array;
int max_nesting;
bool allow_nan;
bool allow_trailing_comma;
@@ -635,7 +636,9 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
action parse_array {
char *np;
+ json->in_array++;
np = JSON_parse_array(json, fpc, pe, result, current_nesting + 1);
+ json->in_array--;
if (np == NULL) { fhold; fbreak; } else fexec np;
}
@@ -897,7 +900,7 @@ static VALUE json_string_fastpath(JSON_Parser *json, char *string, char *stringE
{
size_t bufferSize = stringEnd - string;
- if (is_name) {
+ if (is_name && json->in_array) {
VALUE cached_key;
if (RB_UNLIKELY(symbolize)) {
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);
@@ -920,7 +923,7 @@ static VALUE json_string_unescape(JSON_Parser *json, char *string, char *stringE
int unescape_len;
char buf[4];
- if (is_name) {
+ if (is_name && json->in_array) {
VALUE cached_key;
if (RB_UNLIKELY(symbolize)) {
cached_key = rsymbol_cache_fetch(&json->name_cache, string, bufferSize);