Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Improve JSON Performance

Improve JSON Performance

6e8aca910e7ee095397d3b90acb25f6c?s=128

Watson

May 31, 2018
Tweet

Transcript

  1. *NQSPWF+40/ 1FSGPSNBODF Shizuo Fujita

  2. Self @watson1978 Ubiregi Inc. Ruby committer

  3. JSON.parse()

  4. None
  5. Parsed Hash object require 'json' json =<<'END' { "id": 1,

    "uuid": "ede84c89-3e5a-4025-a8d4-8c66cfed1820", "created_at": "2018-05-27 22:54:55 +0900" } END JSON.parse(json) # => {"id"=>1, # "uuid"=>"ede84c89-3e5a-4025-a8d4-8c66cfed1820", # "created_at"=>"2018-05-27 22:54:55 +0900"} Hash object has String keys.
  6. Hash freezes string key Duplicate and freeze the string if

    it isn’t frozen…
  7. Remove redundant duplication Hash#[]= with frozen string key, you can

    remove redundant duplication of string in internally
  8. Benchmark 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") { JSON.parse(json) } x.report("yajl") { Yajl::Parser.parse(json) } x.report("oj") { Oj.load(json) } end
  9.      KTPO CFGPSF ZBKM KTPO BGUFS

    PK     VQ Before After
  10. JSON.generate() (i.e. Object#to_json)

  11. None
  12. 1. Remove redundant converting array = hash.keys array.each do |key|

    value = hash[key] ... end hash.each do |key, value| ... end Before After Here is pseudo code…
  13. 2. Add shortcut for converting to String for Hash key

    Before it always convert Object to String using #to_s via rb_funcall(). After It convert with appropriate CRuby-API if necessary.
  14. 3. Call CRuby-API instead of rb_funcall rb_funcall() is slightly heavy

    to call the Ruby method. It is better performance to use rb_str_encode() API instead.
  15. 4. Convert encoding only when needed If String object has

    only ASCII characters, it might not need to convert encoding.
  16. Benchmark obj = [] 1000.times do |i| obj << {

    "id" => i, :age => 42, :name => "Foo Bar Baz" } end Benchmark.ips do |x| x.report("json") { JSON.generate(obj) } x.report("yajl") { Yajl::Encoder.encode(obj, nil) } x.report("oj") { Oj.dump(obj) } end
  17.      KTPO CFGPSF ZBKM KTPO BGUFS

    PK     YVQ Before After
  18. Not merged, No reaction Can you help me? https://github.com/flori/json/pull/345 https://github.com/flori/json/pull/346

  19. Thank you !!!