From f68bbd67181718e20bc367a62407967e72efcb46 Mon Sep 17 00:00:00 2001 From: Vipul A M Date: Wed, 9 Apr 2014 11:35:33 +0530 Subject: [PATCH] Perf. improvements to Hash#to_json in pure implementation generator: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Use `.each` instead of `for` for iterating over elements. - Initialize `delim`, `result` vars with initial states instead of appending `state.object_nl` later. - Use faster string interpolation where possible on `Hash#json_transform` instead of appending strings repeatedly. Benchmark: ```ruby hash ={:a => {:a => {:a => {:a => {:a => 1}}}}} require 'benchmark/ips' Benchmark.ips do |x| x.report("to_json ") { hash.to_json} end ``` Before: Calculating ------------------------------------- to_json 4990 i/100ms ------------------------------------------------- to_json 52970.8 (±5.9%) i/s - 264470 in 5.010558s After: Calculating ------------------------------------- to_json 5253 i/100ms ------------------------------------------------- to_json 55998.6 (±5.9%) i/s - 283662 in 5.083350s --- lib/json/pure/generator.rb | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/lib/json/pure/generator.rb b/lib/json/pure/generator.rb index 9056a5d7..f2ad5146 100644 --- a/lib/json/pure/generator.rb +++ b/lib/json/pure/generator.rb @@ -248,7 +248,7 @@ def configure(opts) else raise TypeError, "can't convert #{opts.class} into Hash" end - for key, value in opts + opts.each do |key, value| instance_variable_set "@#{key}", value end @indent = opts[:indent] if opts.key?(:indent) @@ -277,7 +277,7 @@ def configure(opts) # passed to the configure method. def to_h result = {} - for iv in instance_variables + instance_variables.each do |iv| iv = iv.to_s[1..-1] result[iv.to_sym] = self[iv] end @@ -349,21 +349,15 @@ def json_shift(state) end def json_transform(state) - delim = ',' - delim << state.object_nl - result = '{' - result << state.object_nl + delim = ",#{state.object_nl}" + result = "{#{state.object_nl}" depth = state.depth += 1 first = true indent = !state.object_nl.empty? - each { |key,value| + each { |key, value| result << delim unless first result << state.indent * depth if indent - result << key.to_s.to_json(state) - result << state.space_before - result << ':' - result << state.space - result << value.to_json(state) + result = "#{result}#{key.to_s.to_json(state)}#{state.space_before}:#{state.space}#{value.to_json(state)}" first = false } depth = state.depth -= 1