to_json too slow

Posted by Shugo Maeda Tue, 11 Jul 2006 03:51:00 GMT

I felt my application slow yesterday and profiled it. RJS is very useful, but it seems to be slow.

Thanks to Charlies's ruby-prof (it doesn't belongs to me any more and has fascinating call graph support), I found the bottleneck. It was Object#to_json.

The original code is here:

define_encoder String do |string|
  returning value = '"' do
    string.each_char do |char|
      value << case
      when char == "\010":  '\b'
      when char == "\f":    '\f'
      when char == "\n":    '\n'
      when char == "\r":    '\r'
      when char == "\t":    '\t'
      when char == '"':     '\"'
      when char == '\':    '\\'
      when char.length > 1: "\u#{'%04x' % char.unpack('U').first}"
      else;                 char
      end
    end
    value << '"'
  end
end

Ruby can't handle characters fast, so this code is very slow. You'd should use builtin methods such as String#gsub to handle multiple characters at once.

I put the following code into config/environment.rb, and it looks quite fast:)

class String
  JSON_ESCAPED = {
     "\010" =>  '\b',
     "\f" =>    '\f',
     "\n" =>    '\n',
     "\r" =>    '\r',
     "\t" =>    '\t',
     '"' =>     '\"',
     '\' =>    '\\'
  }

  def to_json
    return '"' + gsub(/[\010\f\n\r\t"\]/) { |s|
      JSON_ESCAPED[s]
    } + '"'
  end
end

Then I posted a patch to a related ticket.

If there is any reason to encode multibyte characters, more hacks are needed. I think the best way is to encode multiple multibyte characters at once using String#gsub and String#unpack, Array#pack.

Leave a comment, View comments, View trackbacks

Your Comments.

Leave your own response

Other posts about this post.

This post has been discussed on the following web sites / blogs. If you wish to trackback to this post please use the following trackback address: http://blog.shugo.net/articles/trackback/20

Spread the word.

Shugo's Blog supports RSS (Real Simple Syndication), and Trackbacks from other blogs.

RSS feed for this post Trackback URI

Your Reply

Comment Form.

Fields denoted with a "*" are required.

You may also like to leave your email or website.