rblineprofは計測対象のファイルに計測用のコードを埋め込むことで行単位のプロファイリングが行えるgemです。
rblineprof
の利用方法については【Ruby】rblineprofで行単位の計測を行う方法で紹介していますのであわせてご覧になってください。
rblineprof
にはRackミドルウェア版であるrack-lineprofというgemがあります。
RailsをはじめとしたRackアプリケーションの計測をしたい場合はrblineprof
よりもrack-lineprof
のほうが簡単に設定できます。
rack-lineprof
ではrblineprof
のように計測用のコードを埋め込む必要はありません。
今回はrack-lineprof
の利用方法について紹介します。
目次
下準備: サンプルアプリケーションの作成
今回は例として、N+1問題が発生しているビューの計測をします。
具体的には『生徒一覧画面で生徒名と所属学部を表示する』という画面でN+1問題を発生させます。
rails s
でアプリケーションの起動ができている前提で説明をします。
scaffoldでアプリのひな型を作成
scaffold
でStudentモデル(生徒)とDepartmentモデル(学部)に関するコードを一括作成します。
### scaffoldで関連コードを一括作成
$ rails g scaffold department name
$ rails g scaffold student name department:references
### マイグレーションの実行
$ rails db:migrate
N+1問題が発生する画面の作成
生徒一覧画面を作成します。
student.department.name
がN+1問題の発生する箇所です。
<h1>生徒一覧</h1>
<table>
<thead>
<tr>
<th>生徒名</th>
<th>学部</th>
</tr>
</thead>
<tbody>
<% @students.each do |student| %>
<tr>
<td><%= student.name %></td>
<td><%= student.department.name %></td>
</tr>
<% end %>
</tbody>
</table>
サンプルデータの作成
seed
コマンドを利用してサンプルデータを作成します。
db/seeds.rb
Department.create(name:'経済学部')
Department.create(name:'外国語学部')
Department.create(name:'社会学部')
Department.create(name:'理工学部')
Student.create(name:'鈴木', department_id:1)
Student.create(name:'田中', department_id:2)
Student.create(name:'山田', department_id:3)
Student.create(name:'伊藤', department_id:4)
### seedデータをテーブルにインサート
$ rails db:seed
### seedデータのインサートをやり直したい場合
$ rails db:migrate:reset
$ rails db:seed
画面の確認
localhost:3000/students
にアクセスして以下のような生徒一覧の画面が表示されればOKです。

rack-lineprofの導入手順
ここからはrack-lineprof
の導入手順について紹介します。
rack-lineprofのインストール
Gemfileを修正し、rack-lineprof
をインストールします。
Gemfile
group :development do
gem 'rack-lineprof'
end
$ bundle
Rackミドルウェアに追加する
Rackミドルウェアにlineprof
を追加します。
Railsアプリケーションの場合は以下のようになります。
config/environments/development.rb
Rails.application.configure do
config.middleware.use Rack::Lineprof
end
ミドルウェアスタック一覧にuse Rack::Lineprof
が表示されればOKです。
$ rails middleware | grep Lineprof
use Rack::Lineprof
rack-lineprofを利用した計測方法
rack-lineprofには2つの利用方法があります。
方法1: クエリパラメータを付与する方法
エンドポイントに?lineprof=[計測したいファイル名]
というクエリパラメータを追加してアクセスをすると計測結果が確認できます。
たとえば、生徒の一覧画面(http://localhost:3000/students
)を表示する際のビュー(app/views/students/index.html.erb
)を計測する場合はhttp://localhost:3000/students?lineprof=app/views/students/index.html.erb
となります。
計測結果には『処理にかかった時間』と『呼び出し回数』が表示されます。処理の遅いところは文字がハイライトされます。
http://localhost:3000/students?lineprof=app/views/students/index.html.erb
にアクセスした結果は以下の通りです。

もし、学生の一覧画面(http://localhost:3000/students
)を表示する際のコントローラ(app/controllers/students_controller.rb
)を計測する場合はhttp://localhost:3000/students?lineprof=students_controller.rb
となります。
たとえば以下のようにコントローラを修正します。
students_controller.rb
def index
@students = Student.all
sleep 1
5.times do
sleep 0.1
end
100.times do
sleep 0.001
end
end
コントローラ修正後、http://localhost:3000/students?lineprof=students_controller.rb
にアクセスした結果は以下の通りです。

方法2: ミドルウェアのオプションを利用する方法
rack-lineprof
に用意されているprofile
オプションを利用することでクエリパラメータを省略できます。
たとえば、profile
オプションを利用してapp/views/students/index.html.erb
を計測する場合は以下のようにします。
config/environments/development.rb
Rails.application.configure do
config.middleware.use Rack::Lineprof, profile: 'app/views/students/index.html.erb'
end
上記の設定後http://localhost:3000/students
にアクセスすると、http://localhost:3000/students?lineprof=app/views/students/index.html.erb
と同様の計測ができます。
まとめ
- rack-lineprofはlineprofのRackミドルウェア版
- rack-lineprofは行単位で処理時間と呼び出し回数を計測できる
- エンドポイントに『?lineprof=[ファイル名]』を追加するか、profileオプションにファイル名を指定することで計測ができる
Twitter(@nishina555)やってます。フォローしてもらえるとうれしいです!