From 3ea49e419bdb790ba627318f57a8fb5e818b5a2f Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 1 Nov 2024 17:55:01 +0100 Subject: [PATCH] parser.rl: initialize the buffer with 512B on the stack MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This very significantly reduce the overhead on smaller benchmarks ``` == Parsing small hash (65 bytes) ruby 3.3.4 (2024-07-09 revision be1089c8ec) [arm64-darwin23] Warming up -------------------------------------- json 304.417k i/100ms oj 219.431k i/100ms oj strict 254.532k i/100ms Oj::Parser 431.309k i/100ms rapidjson 281.703k i/100ms Calculating ------------------------------------- json 3.046M (± 0.1%) i/s (328.25 ns/i) - 15.525M in 5.096243s oj 2.225M (± 0.2%) i/s (449.50 ns/i) - 11.191M in 5.030429s oj strict 2.553M (± 0.5%) i/s (391.75 ns/i) - 12.981M in 5.085538s Oj::Parser 4.280M (± 0.8%) i/s (233.64 ns/i) - 21.565M in 5.038834s rapidjson 2.826M (± 0.3%) i/s (353.83 ns/i) - 14.367M in 5.083480s Comparison: json: 3046420.8 i/s Oj::Parser: 4280132.7 i/s - 1.40x faster rapidjson: 2826209.4 i/s - 1.08x slower oj strict: 2552619.7 i/s - 1.19x slower oj: 2224670.7 i/s - 1.37x slower ``` --- ext/json/ext/parser/parser.c | 26 ++++++++++++++++---------- ext/json/ext/parser/parser.rl | 6 ++++++ 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/ext/json/ext/parser/parser.c b/ext/json/ext/parser/parser.c index 983b7dbd..2d107dd3 100644 --- a/ext/json/ext/parser/parser.c +++ b/ext/json/ext/parser/parser.c @@ -1919,17 +1919,20 @@ static VALUE cParser_parse(VALUE self) VALUE result = Qnil; GET_PARSER; + char stack_buffer[FBUFFER_STACK_SIZE]; + fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE); -#line 1924 "parser.c" + +#line 1927 "parser.c" { cs = JSON_start; } -#line 823 "parser.rl" +#line 826 "parser.rl" p = json->source; pe = p + json->len; -#line 1933 "parser.c" +#line 1936 "parser.c" { if ( p == pe ) goto _test_eof; @@ -1973,7 +1976,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 1977 "parser.c" +#line 1980 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2062,7 +2065,7 @@ case 9: _out: {} } -#line 826 "parser.rl" +#line 829 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; @@ -2082,17 +2085,20 @@ static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts) JSON_Parser *json = &parser; parser_init(json, source, opts); + char stack_buffer[FBUFFER_STACK_SIZE]; + fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE); + -#line 2087 "parser.c" +#line 2093 "parser.c" { cs = JSON_start; } -#line 846 "parser.rl" +#line 852 "parser.rl" p = json->source; pe = p + json->len; -#line 2096 "parser.c" +#line 2102 "parser.c" { if ( p == pe ) goto _test_eof; @@ -2136,7 +2142,7 @@ cs = 0; if ( ++p == pe ) goto _test_eof10; case 10: -#line 2140 "parser.c" +#line 2146 "parser.c" switch( (*p) ) { case 13: goto st10; case 32: goto st10; @@ -2225,7 +2231,7 @@ case 9: _out: {} } -#line 849 "parser.rl" +#line 855 "parser.rl" if (cs >= JSON_first_final && p == pe) { return result; diff --git a/ext/json/ext/parser/parser.rl b/ext/json/ext/parser/parser.rl index bb24dd43..ab8e9b82 100644 --- a/ext/json/ext/parser/parser.rl +++ b/ext/json/ext/parser/parser.rl @@ -819,6 +819,9 @@ static VALUE cParser_parse(VALUE self) VALUE result = Qnil; GET_PARSER; + char stack_buffer[FBUFFER_STACK_SIZE]; + fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE); + %% write init; p = json->source; pe = p + json->len; @@ -842,6 +845,9 @@ static VALUE cParser_m_parse(VALUE klass, VALUE source, VALUE opts) JSON_Parser *json = &parser; parser_init(json, source, opts); + char stack_buffer[FBUFFER_STACK_SIZE]; + fbuffer_stack_init(&json->fbuffer, FBUFFER_INITIAL_LENGTH_DEFAULT, stack_buffer, FBUFFER_STACK_SIZE); + %% write init; p = json->source; pe = p + json->len;