From 1a57032cd69c52be0a0e5e7dbf28ceb9f68f7854 Mon Sep 17 00:00:00 2001 From: Watson Date: Mon, 9 Aug 2021 04:31:16 +0900 Subject: [PATCH] Use `rb_enc_get()` to retrieve encoding type (#685) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To reduce overhead, this patch use `rb_enc_get()` instead. − | before | after | result -- | -- | -- | -- Oj.dump | 1.319M | 1.336M | - Oj.dump (compat) | 948.393k | 1.125M | 1.19x Oj.dump (rails) | 815.509k | 943.996k | 1.16x ### Environment - MacBook Air (M1, 2020) - macOS 12.0 beta 4 - Apple M1 - Ruby 3.0.2 ### Before ``` Warming up -------------------------------------- Oj.dump 131.400k i/100ms Oj.dump (compat) 94.239k i/100ms Oj.dump (rails) 79.788k i/100ms Calculating ------------------------------------- Oj.dump 1.319M (± 0.7%) i/s - 6.701M in 5.080504s Oj.dump (compat) 948.393k (± 0.9%) i/s - 4.806M in 5.068098s Oj.dump (rails) 815.509k (± 0.8%) i/s - 4.149M in 5.087955s ``` ### After ``` Warming up -------------------------------------- Oj.dump 133.596k i/100ms Oj.dump (compat) 113.563k i/100ms Oj.dump (rails) 95.233k i/100ms Calculating ------------------------------------- Oj.dump 1.336M (± 1.0%) i/s - 6.680M in 5.000748s Oj.dump (compat) 1.125M (± 0.9%) i/s - 5.678M in 5.046279s Oj.dump (rails) 943.996k (± 0.8%) i/s - 4.762M in 5.044464s ``` ### Test code ```ruby require 'benchmark/ips' require 'oj' json =<<-EOF { "$id": "https://example.com/person.schema.json", "$schema": "https://json-schema.org/draft/2020-12/schema", "title": "Person", "type": "object", "properties": { "firstName": { "type": "string", "description": "The person's first name." }, "lastName": { "type": "string", "description": "The person's last name." }, "age": { "description": "Age in years which must be equal to or greater than zero.", "type": "integer", "minimum": 0 } } } EOF Benchmark.ips do |x| data = Oj.load(json) x.report('Oj.dump') { Oj.dump(data) } x.report('Oj.dump (compat)') { Oj.dump(data, mode: :compat) } x.report('Oj.dump (rails)') { Oj.dump(data, mode: :rails) } end ``` --- ext/oj/dump.c | 6 +++--- ext/oj/parse.c | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/ext/oj/dump.c b/ext/oj/dump.c index 07b4eec2..1d449388 100644 --- a/ext/oj/dump.c +++ b/ext/oj/dump.c @@ -708,10 +708,10 @@ void oj_write_obj_to_stream(VALUE obj, VALUE stream, Options copts) { } void oj_dump_str(VALUE obj, int depth, Out out, bool as_ok) { - rb_encoding *enc = rb_to_encoding(rb_obj_encoding(obj)); + rb_encoding *enc = rb_enc_get(obj); - if (rb_utf8_encoding() != enc) { - obj = rb_str_conv_enc(obj, enc, rb_utf8_encoding()); + if (oj_utf8_encoding != enc) { + obj = rb_str_conv_enc(obj, enc, oj_utf8_encoding); } oj_dump_cstr(RSTRING_PTR(obj), (int)RSTRING_LEN(obj), 0, 0, out); } diff --git a/ext/oj/parse.c b/ext/oj/parse.c index 9094d6a5..992b5253 100644 --- a/ext/oj/parse.c +++ b/ext/oj/parse.c @@ -964,10 +964,10 @@ static VALUE protect_parse(VALUE pip) { extern int oj_utf8_index; static void oj_pi_set_input_str(ParseInfo pi, volatile VALUE *inputp) { - rb_encoding *enc = rb_to_encoding(rb_obj_encoding(*inputp)); + rb_encoding *enc = rb_enc_get(*inputp); - if (rb_utf8_encoding() != enc) { - *inputp = rb_str_conv_enc(*inputp, enc, rb_utf8_encoding()); + if (oj_utf8_encoding != enc) { + *inputp = rb_str_conv_enc(*inputp, enc, oj_utf8_encoding); } pi->json = RSTRING_PTR(*inputp); pi->end = pi->json + RSTRING_LEN(*inputp);