Railsのパフォーマンスtipsトップ10
Top 10 Ruby on Rails performance tipsが面白かったので、ちょっと抜き出してみる。
ここで紹介するものにはサーバの設定は含まれず、コードレベルの話です。
- Rubyのコードを最適化
- ビルトインのクラスやメソッドが使えるときは、自作しないでそっちを使ってね。
- 短いテキストをパースしたり操作するときは、ループするんじゃなくて正規表現を使ってね。
- たまには、ちょっとしたエレガントさや、抽象化は犠牲にしないとダメポ。(define_methodやyieldは重いっす)
- 低速なループの最良の解決法は、それを可能な限りなくすことだ!いつもとはいかないだろうが、いくつかのケースでは、コードの再構築でループを避けることができるよ。
- ネストされたif/unlessを簡単にする。ヒントつ"||="
- ハッシュは重いデータ構造だ。何回か値を使うならローカル変数に入れとけ。頻繁に使われるヤツは変数にしろよ。
- キャッシュするのはいいねぇ
- モデルをキャッシュacts_as_cachedやcached_model
- セッションのコンテナとしてコレを使うMemCacheStore
- 断片化キャッシュでページをキャッシュ。こちらextended_fragment_cache
- 規約を恐れずにデータベースを使え
Railsの決まりごとにしたがってお上品に書くよりも、ストアドプロシージャ等を使っていったほうが速い! - Finderはグレートだぜ。だけど使うときはに気をつけてね
FinderはSQLレベルの知識いらないし、使いやすい。けどね、高度な抽象化というものは重いんだよ。- 必要なものだけとってくる。いらないものを取ってくるから時間がかかるんだ。Finderは「必要なもの」だけをとってくるオプションがあるよ(:select)。それと、結果の中のいくつかだけほしいときは:limitや:offsetがあるよ。
- 莫大なクエリでデータベースを死なすな!ヒントつ:include サンプルコード1
- 動的に作られるFinder(MyModel.find_by_なんたら)は避ける。内部的には(略:原文読んで)。とりあえず重い。
- transactionを使う
ActiveRecordはcreateやupdateをひとつのトランザクションで行う。複数のinsertはいっぱいトランザクションを行うんだ。1 insertにつき1トランザクション。で、ひとつのトランザクションにまとめると速くなるよ。サンプルコード2じゃなくて3を使うんだ。サンプルコード2及び3 - コントローラをコントロール
フィルタは重い。乱用しないでください。また、必要でないのに多くのインスタンス変数を使うな。 - viewにはHTMLを使う
helperを使いすぎないでください。無論、helperを使うとその分、処理が発生します。リンク、テキストボックス、フォームを書くのに本当にhelperが必要ですか? - ログ
必要なログだけとるように設定するんだ。ログは重い。そして、不適切なログレベル(Logger::DEBUG)なんかは生産性を落とすよ。 - Patch the CG
OK、本当にコード化問題ではなく、RubyのGarbage Collectionにパッチするのが強くアドバイスされて、あなたのRubyとRailsアプリケーションの速度をかなり改良するでしょう。
申し訳ない、この部分は良く分からない。 - 最後に
時期尚早な最適化はどうかと思うが、これらを思いつつコーディングするんだ。
サンプルコード1
# This will generates only one query, # rather than Post.count + 1 queries for post in Post.find(:all, :include => [:author, :comments]) # Do something with post end
サンプルコード2
my_collection.each do |q| Quote.create({:phrase => q}) end
サンプルコード3
Quote.transaction do my_collection.each do |q| Quote.create({:phrase => q}) end end