Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't get performance improvements by using the Oj JSON parser

According to https://www.ruby-toolbox.com/categories/JSON_Parsers, I ought to get crazy speedups while serializing hashes using Oj. I've installed the latest gem, included it in my Gemfile, run bundle install, and can confirm that it's getting used. How can _know_ which JSON renderer is active in my Rails 3 app? However, there's been absolutely no speedup in rendering the JSON response.

In a library, I query a legacy MySQL database with Ruby's mysql module. I convert strings to values, and return an array of hashes. This works fine, and it takes about 1.5 to 2 seconds. It should, there's a chunk of data being retrieved here.

CONTROLLER

@data = Gina.points(params[:project], params[:test],
    session[:username], session[:password])
respond_to do |format|
    format.html { render :text => @data }
    format.json { render :json => @data } # :text => MultiJson.engine
end

LIBRARY

dbh = Mysql.real_connect(@@host, u, p)
res = dbh.query("SELECT * FROM #{d}.#{t}")
    @data = []
    res.each_hash do |row|
    obj = {}
        row.each_pair do |k, v|
            v.match(/\A[+-]?\d+?(\.\d+)?\Z/) == nil ? obj[k] = v : obj[k] = v.to_f
        end
    @data << obj
end

My problem is with the 'render :json' part. For about 1.5 MB of data, this can take about 8 or 9 seconds. On larger datasets (3.5 - 4 MB), it can take 25 or 30. I've written around using JSON at all by jamming a string together with "artificial" separators in the library, using a plain .get from jQuery in the view, and then parsing the string into a hash in JS in the browser. I'm down to 1.4 seconds on the smaller sets, and 5 seconds on the larger ones.

The JSON approach is clean and understandable, and is in line with how things were designed to work. The string-parsing approach is a dirty hack, and I don't like it, but it's SIX TIMES faster. The fascinating thing I've learned in comparing the two approaches is that "serializing" my hacky string to JSON is just as quick as "rendering" the text (as there's nothing to do, really). The intensive part of this process is actually serializing a hash, but this is exactly the sort of thing I would expect a "faster" JSON library to do better.

Am I fundamentally misunderstanding what Oj should be doing for me, or am I just doing something wrong?

like image 740
David Krider Avatar asked May 16 '12 13:05

David Krider


1 Answers

You are not using Oj! It will not take effect automatically until you call it explicitly. Replace your original JSON render with

Oj.dump(args)
like image 138
yujingz Avatar answered Sep 29 '22 08:09

yujingz