3

Railsアプリに、読み込みに時間がかかりすぎる、派手な「ワークシート」スタイルのビューがあります。(開発モードでは、キャッシュがないことを知っています。「57893msで完了しました(表示:54975、DB:855)」)ワークシートはヘルパーメソッドを使用してレンダリングされます。ワークシートのさまざまな種類の行。今、パーシャルが実際に速いのではないかと思っていますか?

ページの読み込みをプロファイルし、オブジェクトのキャッシュが数秒短縮されるいくつかのケースを特定しましたが、プロファイルの出力は、ワークシートモデルの構成オブジェクトをループし、からの文字列出力を追加するだけで、かなりの時間が費やされることを示しています。ヘルパー。これが私が話していることの例です:

def header_row(wksht)
  content_tag(:thead, :class => "ioe") do
    content_tag(:tr) do
      html_row = []
      for i in (0...wksht.class::NUM_COLS) do
        html_row << content_tag(:th, h(wksht.column_headings[i].upcase),
                                :class => wksht.column_classes[i])
      end
      html_row.join("\n")
    end
  end
end

パーシャルを使用するOTOHは、ファイルを開き、Rubyインタープリターをスピンオフし、長期的には、一連の文字列を集約することを意味します。だから私はヘルパーで物事をスピードアップする別の方法があるかどうか疑問に思っています。文字列ストリームのようなものを使用する必要がありますか(Rubyに存在しますか?)、独自の ""文字列補間を優先してcontent_tag呼び出しを削除する必要があります...独自のパフォーマンステストを作成し、共有します結果、私がすでに採用したアプローチの代替案があれば。

これはかなり複雑なビューであるため(編集可能なバージョンもあります)、全体を何度も書き直してプロファイルを作成することは避けたいと思います。:)

いくつかの関連する読書:

http://www.viget.com/extend/helpers-vs-partials-a-performance-question/(old)http://www.breakingpointsystems.com/community/blog/ruby-string-processing-overhead/
http _
_ ://blog.purepistos.net/index.php/2008/07/14/benchmarking-ruby-string-interpolation-concatenation-and-appending/

@tadman: 行の合計と列の合計(およびより多くの列の算術)があり、それらはすべて単なる合計ではなく、データベースの他の「マジックナンバー」にも依存するため、JavascriptではなくRubyコードで実装しました。(DRYおよびユニットテスト可能。)Javascriptは編集ビューでのみ使用され、行の追加/削除(クライアント側のみ)およびセルの内容が変更されたときに新しい合計を含むシートをフェッチするためにのみ使用されます。入力セルが変更されると値のほぼ半分が更新されるため、テーブル全体がフェッチされます。

ワークシートとその行は実際には仮想モデルです。それらはDBに存在しませんが、実際のARオブジェクトのボートロードを集約します。ビューがレンダリングされるたびに作成されます(ただし、開発モードでは1.7秒かかるため、心配する必要はありません)。

マークアップされたコンテンツではなく、数字のマトリックスを送信して、JSにシートにアンパックさせることができると思います。しかし、それはすぐに維持できなくなります。

4

2 に答える 2

7

私はhttp://www.infoq.com/articles/Rails-Performance( "A Look At Common Performance Problems In Rails")で優れた記事を読むことになりました。次に、リクエスト処理中に計算をキャッシュするという著者の提案に従いました。

def estimated_costs
  @estimated_costs ||=
    begin
      # tedious vector math
    end
end

私のワークシートは上記のようなことを何度も繰り返し、それらの結果に基づいてさらにいくつかの行を計算するため、これにより、すぐに90%のスピードアップが実現しました。一日のように平凡だったはずですが、それはほんの数個の合計から始まり、それから私は顧客にプロトタイプを見せました、そしてそれはそこから雪だるま式になりました:)

また、配列ベースの計算が非効率的かどうか疑問に思ったので、数値のRuby配列をNArray(http://narray.rubyforge.org/)に置き換えました。スピードアップはごくわずかでしたが、コードはよりクリーンであるため、そのままです。

最後に、オブジェクトキャッシングを配置しました。データベース内の「魔法数」は、せいぜい年に数回しか変更されず、暗号化されているものもありますが、ほとんどの計算で使用する必要があります。これは、キャッシングに適した、ぶら下がっている果物であり、さらに1.25秒短縮されました。

次に、関連付けの積極的な読み込みについて見ていきます。おそらくそこに保存する時間があります。@ tadmanが提案したように、「データのみ」の送信とHTMLの送信を簡単に比較します。キャッシュできる部分はナビゲーションサイドバーだけです。他のすべてのコンテンツは、リクエストパラメータによって異なります。

あなたの提案をありがとう!

于 2010-08-10T18:45:13.597 に答える
4

内部的には、すべてのパーシャルが実行可能なRubyコードのブロックに変換され、ヘルパーメソッドとまったく同じランタイムで実行されます。定期的に、不正な形式のテンプレートが生成されたコードのコンパイルに失敗するときに、これを垣間見ることができます。

ヘルパーメソッドがパーシャルよりも高速であり、単純な文字列補間がさらに高速であるのは当然のことですが、これによるパフォーマンスの向上が追求する価値があるかどうかはわかりません。非常に多くのパーシャルをレンダリングすることは、開発環境でのロギングの観点からはボトルネックになる可能性がありますが、実稼働環境では、それらの影響はそれほど深刻ではないようです。

これを理解する唯一の方法は、2つの異なるレンダリング方法を使用してページをベンチマークすることです。

ご指摘のとおり、キャッシングは大きなメリットを得る場所です。Memcachedを使用して、事前にレンダリングされたHTMLコンテンツの大きなチャンクを保存すると、読み込み時間が飛躍的に速くなります。Rails.cache10,000行をHTMLにレンダリングすることは、サブシステムから同じスニペットを取得するよりも常に遅くなります。

また、レンダリングしないコンテンツは常に最も速くレンダリングされるため、ヘルパー呼び出しごとに生成するコンテンツの量を減らすためにできることはすべて、大きなメリットをもたらします。JavaScriptに完全に依存する大規模なスプレッドシートスタイルのアプリを構築している場合、データをJSON配列としてバンドルし、クライアント側で展開する方が、サーバーでHTMLを展開して出荷するよりもはるかに高速であることがわかります。そのように。

于 2010-08-06T18:07:04.780 に答える