鳩舎

レースしない

speed_gun で Rails のパフォーマンスを測定する

Web アプリケーションのパフォーマンスにうるさいみなさんこんにちは。

Rails アプリのパフォーマンスプロファイリングだと、 rack-mini-profiler が有名で、それ以外だと New Relic とかを使って測定していくのが普通のようですが、物足りない部分があったので、自前でプロファイラ gem を作りました。

Rubygems: http://rubygems.org/gems/speed_gun / Github: https://github.com/rosylilly/speed_gun

詳細は Github の README なんかを見ていただくとして、基本的には rack-mini-profiler 的な情報収集が出来ると思ってもらって差し支えないです。

ちなみに計測画面はこんな感じ。

f:id:rosylilly:20131203183528p:plain

大きなスクリーンショットはこちら

小さくて何も見えないかも……とりあえず3セクションあって、

  1. ブラウザの UserAgent や Performance API などの結果
  2. プロファイル結果
  3. Rack ENVs

となっています(ちなみに画像は Redmine に導入してみたところです。 Gemfile に gem 'speed_gun' って書いたら OK でした)。

rack-mini-profiler には GC を測定する機能とか ruby-prof との連携機能とかあるんですが、一旦その辺はのせていません。もしかしたらあとで実装するかも。

speed_gun はとにかく手早く Rails のプロファイルを取れるように気を使っています。カスタムプロファイラも手軽に作れるようにしています(README の通り)。

また、 JS のプロファイル結果を speed_gun に送るのも簡単に出来るようにしてあります。1つの画面を皆で共有することで、違うブラウザ間でのパフォーマンス測定をより効率的に行えるようにするためです。

Web アプリケーションの『パフォーマンス』は様々なレイヤがあり、Rails のログからだけでは、本当のボトルネックがどこなのかを認識するのが困難だと思っています。たとえば、 Rails は高速に返しているけど、 JS ですごく重い処理があって『パフォーマンス』が悪い気がする、などです。

重いサイトを見てもユーザーさんは『重い』としか言ってくれないので、どこが重いのかを検証するために作りました。

まだまだドキュメント整備不足なので、もっと増やしていくつもりです。

実験的な機能 SpeedGun::Hook

speed_gun には SpeedGun::Hook というクラスがあり、これを継承して #invoke を生やしておくと、そこに保存された SpeedGun::Profilerインスタンスが渡るようになっています。

Javascript プロファイリングの都合上、同じ ID の SpeedGun::Profiler インスタンスが数度呼び出される部分に考慮してコードを書いておくことで、パフォーマンス情報をどこかに永続化する、といったことも可能です。

この辺はまだ API を固めきれていないので今後変更される可能性がありますが、とりあえず僕が試しに使って使用感を確かめようかなというところです。

それでは!