使用Oj JSON解析器无法提高性能

时间:2012-05-16 13:11:05

标签: ruby-on-rails json

根据https://www.ruby-toolbox.com/categories/JSON_Parsers,我应该在使用Oj序列化哈希时获得疯狂的加速。我已经安装了最新的gem,将它包含在我的Gemfile中,运行bundle install,并且可以确认它已经被使用了。 How can _know_ which JSON renderer is active in my Rails 3 app?但是,渲染JSON响应绝对没有加速。

在库中,我使用Ruby的mysql模块查询遗留的MySQL数据库。我将字符串转换为值,并返回一个哈希数组。这很好用,大约需要1.5到2秒。它应该在这里检索一大块数据。

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

我的问题在于'render:json'部分。对于大约1.5 MB的数据,这可能需要大约8或9秒。在较大的数据集(3.5 - 4 MB)上,可能需要25或30.我使用JSON完全使用JSON编写,在库中使用“人工”分隔符将字符串一起使用,在视图中使用jQuery中的普通.get ,然后在浏览器中将字符串解析为JS中的哈希值。我在较小的套装上降至1.4秒,在较大的套装上降至5秒。

JSON方法简洁易懂,符合设计工作方式。字符串解析方法是一个肮脏的黑客,我不喜欢它,但它的速度提高了六倍。我在比较这两种方法时学到的有趣的事情是,将我的hacky字符串“序列化”为JSON与“渲染”文本一样快(因为没有什么可做的,真的)。这个过程的密集部分实际上是序列化一个哈希,但这正是我希望“更快”的JSON库做得更好的事情。

我是否从根本上误解了Oj应该为我做什么,或者我只是做错了什么?

2 个答案:

答案 0 :(得分:2)

你没有使用Oj!在您明确调用它之前,它不会自动生效。用

替换原始的JSON渲染
Oj.dump(args)

答案 1 :(得分:2)

正如this blog post指出的那样,Rails强制json编码方法to_json使用自己的编码实现。这会影响基类,如Array,Hash和Integer。

这意味着在json编码期间默认情况下根本不使用multi_json和oj,这就是你觉得它很慢的原因。

您可以手动使用Oj进行编码,如@yujingz指出的那样。

作为替代方案,我使用博客文章来创建a patch gem来代替使用MultiJson,它应该自动使用Oj进行编码。