在Rails中呈现JSON的最快方法是什么?

45

我正在优化我们的Rails应用程序中一些缓慢的事务,我发现在渲染JSON视图时花费了大量时间:

Rendered welcome/index.json.rabl (490.5ms)
Completed 200 OK in 1174ms (Views: 479.6ms | ActiveRecord: 27.8ms)

假设API调用恰好返回了需要的数据,在Rails中渲染JSON的最快方式是什么?

我们使用Rabl,因为它可以轻松共享代码,但我们并不局限于它。


4
加快速度的最简单方法是确保控制器已经加载了视图所需的所有数据。通常,缓慢的视图是由于查找未预先加载的关联引起的。 - Gareth
2
请注意,ActiveRecord的时间为27.8毫秒,这里没有太多的数据。我们使用.includes或其他技术进行了大量的急切加载。我很好奇除了视图或ActiveRecord之外的700毫秒花在了哪里,但这是另一个问题。 - John Naegle
在Rabl中开启缓存并切换到yajl,显著降低了第二个请求的时间:渲染welcome/index.json.rabl (321.9毫秒) 完成200 OK请求,用时893毫秒(视图:311.0毫秒 | ActiveRecord:27.2毫秒) - John Naegle
@JohnNaegle 你能找出响应调用中其他700的花费去向吗?如果可以,你认为最好的跟踪方式是什么? - boddhisattva
我还没有 - 我很想知道时间都花在哪里了。 - John Naegle
2
@JohnNaegle 有关解决方案的任何更新吗?如果找到了,请告知。Rails 4也存在同样的问题。 - Deepender Singla
4个回答

45

目前 oj 似乎是最快的渲染器 - 根据 oj 作者的 comparison

最新的 multi_json 默认使用 Oj(Rails 默认使用 mutli_json),因此切换到 Oj 应该很简单,只需将以下内容添加到您的 Gemfile 中即可:

  # Gemfile
  gem "oj"

每次调用 render 时,它现在将使用 oj。
  render :json => { ... } # uses multi_json which uses oj

Oj还提供了其他特定的接口,如果您想获得更高的性能,但使用multi_json可以更容易地替换宝石。

请注意,如果您有任何{ ... }.to_json调用-这些调用将不会升级为使用oj,除非您在初始化程序中调用Oj.mimic_JSON


1
我尝试将Oj.mimic_JSON放在初始化程序中,但它会引发一个关于JSON已经被要求的错误。是否还有其他步骤可以采取来停止某个地方对JSON模块的要求?谢谢。 - Nik So
根据我的测试,Oj比multi_json快得多。 - coderz

17

Rails 3使用multi_json,但只用于JSON解码,而不是编码。JSON编码/渲染/生成使用 ActiveSupport JSON库的to_json方法,因此始终很慢(即使您使用了Oj gem)。

您可以通过以下方式显式地使用multi_json进行渲染:

render :json => MultiJson.dump(@posts)

或者你可以尝试使用rails-patch-json-encode gem(由我创建),它默认使用multi_json。它将影响所有内置的to_json方法,所以请确保所有测试都通过。


1
哇!MultiJson::dump非常快!感谢提到这点。 - sixty4bit

14

Rabl使用multi_json以实现跨平台兼容性,并且默认情况下不使用相当快速的Yajl库。 Rabl的配置文档中解释了解决方案:

# Gemfile
gem 'yajl-ruby', :require => "yajl"

如果这还不够高效,你可能想要尝试使用另一个 JSON 序列化器,比如oj。你也可以检测你的渲染过程并查看瓶颈存在的位置。


我阅读了“also instrument”链接,但并不清楚它如何转化为轻松地找到性能问题。你当时的想法是什么? - Rob
Rob,也许这个屏幕录像能够帮你理清思路。http://railscasts.com/episodes/249-notifications-in-rails-3?autoplay=true 致以问候。 - Nik So

0

最近,Netflix发布了一个新的JSON渲染库,据说比默认库快25-40倍。公告代码。你需要创建一个新的序列化器来利用它,但对于受影响的人来说,这似乎不是什么大问题。


1
fast_jsonapi 遵循 http://jsonapi.org 的规范。因此,您将无法按照自己的方式构建 json。您无法摆脱“data”、“relationships”和其他包装器。请参见 此 GitHub 问题 - user1476061
fast_jsonapi 过于主观。如果一个人想按照自己的方式构建 JSON 输出,我不建议使用这个库。 - fade2black

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接