From 38c0f6dbe4d6709988eecd6b04c59a48066de876 Mon Sep 17 00:00:00 2001 From: Watson Date: Fri, 2 Mar 2018 00:45:28 +0900 Subject: [PATCH] Add shortcut converting to String MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In where to convert Hash key to String for json, this patch will add shortcut for String/Symbol in Hash key. ``` $ ruby bench_json_generate.rb Warming up -------------------------------------- json 65.000 i/100ms Calculating ------------------------------------- json 659.576 (± 1.5%) i/s - 3.315k in 5.027127s ``` ``` $ ruby bench_json_generate.rb Warming up -------------------------------------- json 78.000 i/100ms Calculating ------------------------------------- json 789.781 (± 2.7%) i/s - 3.978k in 5.041043s ``` ``` require 'json' require 'benchmark/ips' obj = [] 1000.times do |i| obj << { "id" => i, :age => 42, } end Benchmark.ips do |x| x.report "json" do |iter| count = 0 while count < iter JSON.generate(obj) count += 1 end end end ``` --- ext/json/ext/generator/generator.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/ext/json/ext/generator/generator.c b/ext/json/ext/generator/generator.c index e4412361..30d575db 100644 --- a/ext/json/ext/generator/generator.c +++ b/ext/json/ext/generator/generator.c @@ -740,7 +740,7 @@ json_object_i(VALUE key, VALUE val, VALUE _arg) long delim2_len = FBUFFER_LEN(state->object_delim2); long depth = state->depth; int j; - VALUE key_to_s; + VALUE klass, key_to_s; if (arg->iter > 0) fbuffer_append(buffer, delim, delim_len); if (object_nl) { @@ -752,7 +752,14 @@ json_object_i(VALUE key, VALUE val, VALUE _arg) } } - key_to_s = rb_funcall(key, i_to_s, 0); + klass = CLASS_OF(key); + if (klass == rb_cString) { + key_to_s = key; + } else if (klass == rb_cSymbol) { + key_to_s = rb_id2str(SYM2ID(key)); + } else { + key_to_s = rb_funcall(key, i_to_s, 0); + } Check_Type(key_to_s, T_STRING); generate_json(buffer, Vstate, state, key_to_s); fbuffer_append(buffer, delim2, delim2_len);