10

私が取り組んでいるアプリは、ほとんどのリクエストに JSON オブジェクトまたはそのコレクションで応答します。これらの応答を作成するためにJbuilderを使用しています。レンダリングされるデータの量はかなり大きいです (さまざまなネストされた構造の数千のオブジェクト - フォーマットされて完全に展開されると、典型的な応答には 10,000 行もの JSON があります)。NewRelic によると、このレンダリングにはかなりの時間がかかっています。合計リクエスト時間の約 1/3 です。

JBuilder から可能な限り最高のパフォーマンスを引き出すのに役立つ何らかのガイド、一連のヒント、またはその他のリソースを探しています。また、Jbuilder とRABLまたは他の同様のツールで利用可能なパフォーマンス比較があるかどうかも知りたいです。

編集: Jbuilder のパフォーマンスについて不平を言うGitHub の問題を見つけましたが、誰かが行った唯一の実際の提案は「Jbuilder を使用しないでください」です。実際、彼らは少し強力な言語を使用していましたが、なぜJbuilder が非常に遅いのか、それを回避するために何ができるのか、または同じタスクに対する他のツールとの比較についてはまだ語られていません。

4

3 に答える 3

12

jbuilderは、データを含む大きなハッシュを構築し、それを使用ActiveSupport::JSONしてjsonに変換します。次のマイクロベンチマークが示すように、より高速なjsonエミッターがあります(multijsonおよびyajl-ruby gemがインストールされていることを確認してください)

require 'benchmark'
require 'active_support'
require 'multi_json'
sample = {menu: {
    header: "SVG Viewer",
    items: [
        {id: "Open"},
        {id: "OpenNew", label: "Open New"},
        nil,
        {id: "ZoomIn", label: "Zoom In"},
        {id: "ZoomOut", label: "Zoom Out"},
        {id: "OriginalView", label: "Original View"},
        nil,
        {id: "Quality"},
        {id: "Pause"},
        {id: "Mute"},
        nil,
        {id: "Find", label: "Find..."},
        {id: "FindAgain", label: "Find Again"},
        {id: "Copy"},
        {id: "CopyAgain", label: "Copy Again"},
        {id: "CopySVG", label: "Copy SVG"},
        {id: "ViewSVG", label: "View SVG"},
        {id: "ViewSource", label: "View Source"},
        {id: "SaveAs", label: "Save As"},
        nil,
        {id: "Help"},
        {id: "About", label: "About Adobe CVG Viewer..."}
    ]
}}


MultiJson.engine = :yajl
Benchmark.bmbm(5) do |x|
  x.report 'activesupport' do
    1000.times {ActiveSupport::JSON.encode(sample)}
  end
  x.report 'yajl' do
    1000.times {MultiJson.encode(sample)}
  end
end

私のマシンでは、これは

                    user     system      total        real
activesupport   1.050000   0.010000   1.060000 (  1.068426)
yajl            0.020000   0.000000   0.020000 (  0.021169)

つまり、サンプルオブジェクトを1000回エンコードするには、アクティブなサポートに1秒以上かかり、MultiJson(yajlエンジンを使用)には21ミリ秒かかりました。

JBuilderはActiveSupport::JSONを使用するようにハードコーディングされていますが、MultiJSON(jsonライブラリを切り替えることができるgem)は簡単なドロップインであり、すでにActiveSupportに依存しています-jbuilderの私のフォークを参照してください。プルリクエストを開きましたが、それまではこのフォークを使用してみてください(または独自のフォークを作成してください-これは1行の変更です)

于 2012-06-14T16:22:45.130 に答える
4

Rabl に切り替えて、キャッシングを追加することを検討してください。ネストされた構造に何千ものオブジェクトがある場合、結果の JSON の一部のノードをパーシャルとしてレンダリングしてキャッシュすることができます。パフォーマンスが大幅に向上する可能性があります。

これを除けば、Rabl のパフォーマンスは JBuilder のパフォーマンスよりもわずかに優れていますが、Rabl の構文は時々混乱するので、フラグメント キャッシュが実装されたら JBuilder に切り替えます。

于 2012-06-20T11:26:17.190 に答える