Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 18292c0

Browse files
Watson1978marcandre
authored andcommittedJun 25, 2020
Use frozen string for hash key
When use non-frozen string for hash key with `rb_hash_aset()`, it will duplicate and freeze it internally. To avoid duplicate and freeze, this patch will give a frozen string in `rb_hash_aset()`. ``` Warming up -------------------------------------- json 14.000 i/100ms Calculating ------------------------------------- json 148.844 (± 1.3%) i/s - 756.000 in 5.079969s ``` ``` Warming up -------------------------------------- json 16.000 i/100ms Calculating ------------------------------------- json 165.608 (± 1.8%) i/s - 832.000 in 5.025367s ``` ``` require 'json' require 'securerandom' require 'benchmark/ips' obj = [] 1000.times do |i| obj << { "id": i, "uuid": SecureRandom.uuid, "created_at": Time.now } end json = obj.to_json Benchmark.ips do |x| x.report "json" do |iter| count = 0 while count < iter JSON.parse(json) count += 1 end end end ```
1 parent fb6eefe commit 18292c0

File tree

2 files changed

+69
-67
lines changed

2 files changed

+69
-67
lines changed
 

‎ext/json/ext/parser/parser.c‎

Lines changed: 68 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ enum {JSON_object_error = 0};
112112
enum {JSON_object_en_main = 1};
113113

114114

115-
#line 167 "parser.rl"
115+
#line 168 "parser.rl"
116116

117117

118118
static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -133,7 +133,7 @@ static char *JSON_parse_object(JSON_Parser *json, char *p, char *pe, VALUE *resu
133133
cs = JSON_object_start;
134134
}
135135

136-
#line 182 "parser.rl"
136+
#line 183 "parser.rl"
137137

138138
#line 139 "parser.c"
139139
{
@@ -163,7 +163,7 @@ case 2:
163163
goto st2;
164164
goto st0;
165165
tr2:
166-
#line 149 "parser.rl"
166+
#line 150 "parser.rl"
167167
{
168168
char *np;
169169
json->parsing_name = 1;
@@ -251,6 +251,7 @@ case 8:
251251
p--; {p++; cs = 9; goto _out;}
252252
} else {
253253
if (NIL_P(json->object_class)) {
254+
OBJ_FREEZE(last_name);
254255
rb_hash_aset(*result, last_name, v);
255256
} else {
256257
rb_funcall(*result, i_aset, 2, last_name, v);
@@ -263,7 +264,7 @@ case 8:
263264
if ( ++p == pe )
264265
goto _test_eof9;
265266
case 9:
266-
#line 267 "parser.c"
267+
#line 268 "parser.c"
267268
switch( (*p) ) {
268269
case 13: goto st9;
269270
case 32: goto st9;
@@ -352,14 +353,14 @@ case 18:
352353
goto st9;
353354
goto st18;
354355
tr4:
355-
#line 157 "parser.rl"
356+
#line 158 "parser.rl"
356357
{ p--; {p++; cs = 27; goto _out;} }
357358
goto st27;
358359
st27:
359360
if ( ++p == pe )
360361
goto _test_eof27;
361362
case 27:
362-
#line 363 "parser.c"
363+
#line 364 "parser.c"
363364
goto st0;
364365
st19:
365366
if ( ++p == pe )
@@ -457,7 +458,7 @@ case 26:
457458
_out: {}
458459
}
459460

460-
#line 183 "parser.rl"
461+
#line 184 "parser.rl"
461462

462463
if (cs >= JSON_object_first_final) {
463464
if (json->create_additions) {
@@ -482,30 +483,30 @@ case 26:
482483

483484

484485

485-
#line 486 "parser.c"
486+
#line 487 "parser.c"
486487
enum {JSON_value_start = 1};
487488
enum {JSON_value_first_final = 29};
488489
enum {JSON_value_error = 0};
489490

490491
enum {JSON_value_en_main = 1};
491492

492493

493-
#line 283 "parser.rl"
494+
#line 284 "parser.rl"
494495

495496

496497
static char *JSON_parse_value(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
497498
{
498499
int cs = EVIL;
499500

500501

501-
#line 502 "parser.c"
502+
#line 503 "parser.c"
502503
{
503504
cs = JSON_value_start;
504505
}
505506

506-
#line 290 "parser.rl"
507+
#line 291 "parser.rl"
507508

508-
#line 509 "parser.c"
509+
#line 510 "parser.c"
509510
{
510511
if ( p == pe )
511512
goto _test_eof;
@@ -539,14 +540,14 @@ case 1:
539540
cs = 0;
540541
goto _out;
541542
tr2:
542-
#line 235 "parser.rl"
543+
#line 236 "parser.rl"
543544
{
544545
char *np = JSON_parse_string(json, p, pe, result);
545546
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
546547
}
547548
goto st29;
548549
tr3:
549-
#line 240 "parser.rl"
550+
#line 241 "parser.rl"
550551
{
551552
char *np;
552553
if(pe > p + 8 && !strncmp(MinusInfinity, p, 9)) {
@@ -566,23 +567,23 @@ cs = 0;
566567
}
567568
goto st29;
568569
tr7:
569-
#line 258 "parser.rl"
570+
#line 259 "parser.rl"
570571
{
571572
char *np;
572573
np = JSON_parse_array(json, p, pe, result, current_nesting + 1);
573574
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
574575
}
575576
goto st29;
576577
tr11:
577-
#line 264 "parser.rl"
578+
#line 265 "parser.rl"
578579
{
579580
char *np;
580581
np = JSON_parse_object(json, p, pe, result, current_nesting + 1);
581582
if (np == NULL) { p--; {p++; cs = 29; goto _out;} } else {p = (( np))-1;}
582583
}
583584
goto st29;
584585
tr25:
585-
#line 228 "parser.rl"
586+
#line 229 "parser.rl"
586587
{
587588
if (json->allow_nan) {
588589
*result = CInfinity;
@@ -592,7 +593,7 @@ cs = 0;
592593
}
593594
goto st29;
594595
tr27:
595-
#line 221 "parser.rl"
596+
#line 222 "parser.rl"
596597
{
597598
if (json->allow_nan) {
598599
*result = CNaN;
@@ -602,19 +603,19 @@ cs = 0;
602603
}
603604
goto st29;
604605
tr31:
605-
#line 215 "parser.rl"
606+
#line 216 "parser.rl"
606607
{
607608
*result = Qfalse;
608609
}
609610
goto st29;
610611
tr34:
611-
#line 212 "parser.rl"
612+
#line 213 "parser.rl"
612613
{
613614
*result = Qnil;
614615
}
615616
goto st29;
616617
tr37:
617-
#line 218 "parser.rl"
618+
#line 219 "parser.rl"
618619
{
619620
*result = Qtrue;
620621
}
@@ -623,9 +624,9 @@ cs = 0;
623624
if ( ++p == pe )
624625
goto _test_eof29;
625626
case 29:
626-
#line 270 "parser.rl"
627+
#line 271 "parser.rl"
627628
{ p--; {p++; cs = 29; goto _out;} }
628-
#line 629 "parser.c"
629+
#line 630 "parser.c"
629630
switch( (*p) ) {
630631
case 13: goto st29;
631632
case 32: goto st29;
@@ -866,7 +867,7 @@ case 28:
866867
_out: {}
867868
}
868869

869-
#line 291 "parser.rl"
870+
#line 292 "parser.rl"
870871

871872
if (cs >= JSON_value_first_final) {
872873
return p;
@@ -876,31 +877,31 @@ case 28:
876877
}
877878

878879

879-
#line 880 "parser.c"
880+
#line 881 "parser.c"
880881
enum {JSON_integer_start = 1};
881882
enum {JSON_integer_first_final = 3};
882883
enum {JSON_integer_error = 0};
883884

884885
enum {JSON_integer_en_main = 1};
885886

886887

887-
#line 307 "parser.rl"
888+
#line 308 "parser.rl"
888889

889890

890891
static char *JSON_parse_integer(JSON_Parser *json, char *p, char *pe, VALUE *result)
891892
{
892893
int cs = EVIL;
893894

894895

895-
#line 896 "parser.c"
896+
#line 897 "parser.c"
896897
{
897898
cs = JSON_integer_start;
898899
}
899900

900-
#line 314 "parser.rl"
901+
#line 315 "parser.rl"
901902
json->memo = p;
902903

903-
#line 904 "parser.c"
904+
#line 905 "parser.c"
904905
{
905906
if ( p == pe )
906907
goto _test_eof;
@@ -934,14 +935,14 @@ case 3:
934935
goto st0;
935936
goto tr4;
936937
tr4:
937-
#line 304 "parser.rl"
938+
#line 305 "parser.rl"
938939
{ p--; {p++; cs = 4; goto _out;} }
939940
goto st4;
940941
st4:
941942
if ( ++p == pe )
942943
goto _test_eof4;
943944
case 4:
944-
#line 945 "parser.c"
945+
#line 946 "parser.c"
945946
goto st0;
946947
st5:
947948
if ( ++p == pe )
@@ -960,7 +961,7 @@ case 5:
960961
_out: {}
961962
}
962963

963-
#line 316 "parser.rl"
964+
#line 317 "parser.rl"
964965

965966
if (cs >= JSON_integer_first_final) {
966967
long len = p - json->memo;
@@ -975,15 +976,15 @@ case 5:
975976
}
976977

977978

978-
#line 979 "parser.c"
979+
#line 980 "parser.c"
979980
enum {JSON_float_start = 1};
980981
enum {JSON_float_first_final = 8};
981982
enum {JSON_float_error = 0};
982983

983984
enum {JSON_float_en_main = 1};
984985

985986

986-
#line 341 "parser.rl"
987+
#line 342 "parser.rl"
987988

988989

989990
static int is_bigdecimal_class(VALUE obj)
@@ -1004,15 +1005,15 @@ static char *JSON_parse_float(JSON_Parser *json, char *p, char *pe, VALUE *resul
10041005
int cs = EVIL;
10051006

10061007

1007-
#line 1008 "parser.c"
1008+
#line 1009 "parser.c"
10081009
{
10091010
cs = JSON_float_start;
10101011
}
10111012

1012-
#line 361 "parser.rl"
1013+
#line 362 "parser.rl"
10131014
json->memo = p;
10141015

1015-
#line 1016 "parser.c"
1016+
#line 1017 "parser.c"
10161017
{
10171018
if ( p == pe )
10181019
goto _test_eof;
@@ -1070,14 +1071,14 @@ case 8:
10701071
goto st0;
10711072
goto tr9;
10721073
tr9:
1073-
#line 335 "parser.rl"
1074+
#line 336 "parser.rl"
10741075
{ p--; {p++; cs = 9; goto _out;} }
10751076
goto st9;
10761077
st9:
10771078
if ( ++p == pe )
10781079
goto _test_eof9;
10791080
case 9:
1080-
#line 1081 "parser.c"
1081+
#line 1082 "parser.c"
10811082
goto st0;
10821083
st5:
10831084
if ( ++p == pe )
@@ -1138,7 +1139,7 @@ case 7:
11381139
_out: {}
11391140
}
11401141

1141-
#line 363 "parser.rl"
1142+
#line 364 "parser.rl"
11421143

11431144
if (cs >= JSON_float_first_final) {
11441145
long len = p - json->memo;
@@ -1164,15 +1165,15 @@ case 7:
11641165

11651166

11661167

1167-
#line 1168 "parser.c"
1168+
#line 1169 "parser.c"
11681169
enum {JSON_array_start = 1};
11691170
enum {JSON_array_first_final = 17};
11701171
enum {JSON_array_error = 0};
11711172

11721173
enum {JSON_array_en_main = 1};
11731174

11741175

1175-
#line 416 "parser.rl"
1176+
#line 417 "parser.rl"
11761177

11771178

11781179
static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *result, int current_nesting)
@@ -1186,14 +1187,14 @@ static char *JSON_parse_array(JSON_Parser *json, char *p, char *pe, VALUE *resul
11861187
*result = NIL_P(array_class) ? rb_ary_new() : rb_class_new_instance(0, 0, array_class);
11871188

11881189

1189-
#line 1190 "parser.c"
1190+
#line 1191 "parser.c"
11901191
{
11911192
cs = JSON_array_start;
11921193
}
11931194

1194-
#line 429 "parser.rl"
1195+
#line 430 "parser.rl"
11951196

1196-
#line 1197 "parser.c"
1197+
#line 1198 "parser.c"
11971198
{
11981199
if ( p == pe )
11991200
goto _test_eof;
@@ -1232,7 +1233,7 @@ case 2:
12321233
goto st2;
12331234
goto st0;
12341235
tr2:
1235-
#line 393 "parser.rl"
1236+
#line 394 "parser.rl"
12361237
{
12371238
VALUE v = Qnil;
12381239
char *np = JSON_parse_value(json, p, pe, &v, current_nesting);
@@ -1252,7 +1253,7 @@ case 2:
12521253
if ( ++p == pe )
12531254
goto _test_eof3;
12541255
case 3:
1255-
#line 1256 "parser.c"
1256+
#line 1257 "parser.c"
12561257
switch( (*p) ) {
12571258
case 13: goto st3;
12581259
case 32: goto st3;
@@ -1352,14 +1353,14 @@ case 12:
13521353
goto st3;
13531354
goto st12;
13541355
tr4:
1355-
#line 408 "parser.rl"
1356+
#line 409 "parser.rl"
13561357
{ p--; {p++; cs = 17; goto _out;} }
13571358
goto st17;
13581359
st17:
13591360
if ( ++p == pe )
13601361
goto _test_eof17;
13611362
case 17:
1362-
#line 1363 "parser.c"
1363+
#line 1364 "parser.c"
13631364
goto st0;
13641365
st13:
13651366
if ( ++p == pe )
@@ -1415,7 +1416,7 @@ case 16:
14151416
_out: {}
14161417
}
14171418

1418-
#line 430 "parser.rl"
1419+
#line 431 "parser.rl"
14191420

14201421
if(cs >= JSON_array_first_final) {
14211422
return p + 1;
@@ -1504,15 +1505,15 @@ static VALUE json_string_unescape(VALUE result, char *string, char *stringEnd)
15041505
}
15051506

15061507

1507-
#line 1508 "parser.c"
1508+
#line 1509 "parser.c"
15081509
enum {JSON_string_start = 1};
15091510
enum {JSON_string_first_final = 8};
15101511
enum {JSON_string_error = 0};
15111512

15121513
enum {JSON_string_en_main = 1};
15131514

15141515

1515-
#line 537 "parser.rl"
1516+
#line 538 "parser.rl"
15161517

15171518

15181519
static int
@@ -1534,15 +1535,15 @@ static char *JSON_parse_string(JSON_Parser *json, char *p, char *pe, VALUE *resu
15341535

15351536
*result = rb_str_buf_new(0);
15361537

1537-
#line 1538 "parser.c"
1538+
#line 1539 "parser.c"
15381539
{
15391540
cs = JSON_string_start;
15401541
}
15411542

1542-
#line 558 "parser.rl"
1543+
#line 559 "parser.rl"
15431544
json->memo = p;
15441545

1545-
#line 1546 "parser.c"
1546+
#line 1547 "parser.c"
15461547
{
15471548
if ( p == pe )
15481549
goto _test_eof;
@@ -1567,7 +1568,7 @@ case 2:
15671568
goto st0;
15681569
goto st2;
15691570
tr2:
1570-
#line 523 "parser.rl"
1571+
#line 524 "parser.rl"
15711572
{
15721573
*result = json_string_unescape(*result, json->memo + 1, p);
15731574
if (NIL_P(*result)) {
@@ -1578,14 +1579,14 @@ case 2:
15781579
{p = (( p + 1))-1;}
15791580
}
15801581
}
1581-
#line 534 "parser.rl"
1582+
#line 535 "parser.rl"
15821583
{ p--; {p++; cs = 8; goto _out;} }
15831584
goto st8;
15841585
st8:
15851586
if ( ++p == pe )
15861587
goto _test_eof8;
15871588
case 8:
1588-
#line 1589 "parser.c"
1589+
#line 1590 "parser.c"
15891590
goto st0;
15901591
st3:
15911592
if ( ++p == pe )
@@ -1661,7 +1662,7 @@ case 7:
16611662
_out: {}
16621663
}
16631664

1664-
#line 560 "parser.rl"
1665+
#line 561 "parser.rl"
16651666

16661667
if (json->create_additions && RTEST(match_string = json->match_string)) {
16671668
VALUE klass;
@@ -1848,15 +1849,15 @@ static VALUE cParser_initialize(int argc, VALUE *argv, VALUE self)
18481849
}
18491850

18501851

1851-
#line 1852 "parser.c"
1852+
#line 1853 "parser.c"
18521853
enum {JSON_start = 1};
18531854
enum {JSON_first_final = 10};
18541855
enum {JSON_error = 0};
18551856

18561857
enum {JSON_en_main = 1};
18571858

18581859

1859-
#line 760 "parser.rl"
1860+
#line 761 "parser.rl"
18601861

18611862

18621863
/*
@@ -1873,16 +1874,16 @@ static VALUE cParser_parse(VALUE self)
18731874
GET_PARSER;
18741875

18751876

1876-
#line 1877 "parser.c"
1877+
#line 1878 "parser.c"
18771878
{
18781879
cs = JSON_start;
18791880
}
18801881

1881-
#line 776 "parser.rl"
1882+
#line 777 "parser.rl"
18821883
p = json->source;
18831884
pe = p + json->len;
18841885

1885-
#line 1886 "parser.c"
1886+
#line 1887 "parser.c"
18861887
{
18871888
if ( p == pe )
18881889
goto _test_eof;
@@ -1916,7 +1917,7 @@ case 1:
19161917
cs = 0;
19171918
goto _out;
19181919
tr2:
1919-
#line 752 "parser.rl"
1920+
#line 753 "parser.rl"
19201921
{
19211922
char *np = JSON_parse_value(json, p, pe, &result, 0);
19221923
if (np == NULL) { p--; {p++; cs = 10; goto _out;} } else {p = (( np))-1;}
@@ -1926,7 +1927,7 @@ cs = 0;
19261927
if ( ++p == pe )
19271928
goto _test_eof10;
19281929
case 10:
1929-
#line 1930 "parser.c"
1930+
#line 1931 "parser.c"
19301931
switch( (*p) ) {
19311932
case 13: goto st10;
19321933
case 32: goto st10;
@@ -2015,7 +2016,7 @@ case 9:
20152016
_out: {}
20162017
}
20172018

2018-
#line 779 "parser.rl"
2019+
#line 780 "parser.rl"
20192020

20202021
if (cs >= JSON_first_final && p == pe) {
20212022
return result;

‎ext/json/ext/parser/parser.rl‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ static ID i_json_creatable_p, i_json_create, i_create_id, i_create_additions,
138138
fhold; fbreak;
139139
} else {
140140
if (NIL_P(json->object_class)) {
141+
OBJ_FREEZE(last_name);
141142
rb_hash_aset(*result, last_name, v);
142143
} else {
143144
rb_funcall(*result, i_aset, 2, last_name, v);

0 commit comments

Comments
 (0)
Please sign in to comment.