Octopressで記事数が増えてきてgenerateするのが結構辛くなってきたので 取り敢えずどれ位時間がかかってるのか測ってみました。
その際にRubyのBenchmarkというモジュールが便利だったのでそれについて。
Benchmark
RubyでBenchmarkというモジュールを使うと簡単に 関数等の実行時間を計測して表示することが出来ます。
measure
基本的な使い方は
| 1 2 |  | 
みたいな形でcmdとういうコマンドでどれだけ時間がかかったか取得できます。
複数行コマンドの場合は;で繋げて入れる事が出来ます。
出力にはtimeコマンドの様にuser、system、total、realの項目があります。
| 1
 |  | 
とか直接出力すれば
0.620000   0.010000   0.630000 (  0.640026)
みたいな表示が得られます。
Benchmark::CAPTIONという値が
user     system      total        real
となってるので
| 1 2 |  | 
とかすると
      user     system      total        real
  0.620000   0.010000   0.630000 (  0.640026)
みたいに表示できます。
bm
複数のコマンドを順次計測して表示したい場合には
Benchmark.bmが使えます。
使い方はこんな感じ:
| 1 2 3 4 5 |  | 
bmの引数の数字はレポート時に表示されるコマンドの名前の長さを整えるのに使われる数字です。
(この数だけ繰り返される、とか、実行するコマンドの数、とかではありません。)
ブロックの中ではreportという関数を使って、()中にコマンド名(レポート表示用)、
{}の中に実際に行うコマンドを入れます。
結果は直接こんな感じでまとめて表示されます。
                 user     system      total        real
command 1    0.000000   0.000000   0.000000 (  0.000005)
command 2    0.000000   0.000000   0.000000 (  0.000005)
command 3    0.000000   0.000000   0.000000 (  0.000005)
ただし、cmd2とかが標準出力を出す様なものだとこの表の途中に紛れ込んだりするので、
適時出力先を変えるか、
もしくは上のmeasureで一つ一つ結果を保存しておいてあとで表示、みたいな
事をした方が良い時もあります。
Octopressの基本的なgenerateの時間を測ってみる
Octopressのgenerateタスクではjekyll buildを呼んでるわけですが、
実際jekyllコマンドの中で行われてる作業を幾つかに区切って時間を測ってみました。
まず、jekyllのモジュールの中身を見て見るために
$ gem which jekyll
/Library/Ruby/Gems/2.0.0/gems/jekyll-2.5.3/lib/jekyll.rb
でインストール場所を確認。 この付近で/Library/Ruby/Gems/2.0.0/gems/jekyll-2.5.3/lib/jekyll/commands/build.rb を見つけたので中をみてみると
| 1 2 3 4 5 6 7 8 9 10 |  | 
という箇所があって、このprocess_siteという関数は
/Library/Ruby/Gems/2.0.0/gems/jekyll-2.5.3/lib/jekyll/command.rbの中で
| 1 2 3 4 5 |  | 
と言った形で定義されてます。 最後に /Library/Ruby/Gems/2.0.0/gems/jekyll-2.5.3/lib/jekyll/site.rb を見ると
| 1 2 3 4 5 6 7 8 9 10 11 |  | 
という箇所があるので、取り敢えずここで実行されてる関数ごとに時間を測ってみたいと思います。
こういう時に、Rubyではこういった定義されてる関数を直接いじらずに外から オーバーライドすることが出来るので便利です。
plugins/jekyll_patch.rbというファイルを作って、
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |  | 
こんな感じでprocessを書き換えてあげます。
これでrake generateすると
                 user     system      total        real
reset        0.010000   0.000000   0.010000 (  0.018111)
read         0.430000   0.110000   0.540000 (  0.596607)
generate    61.080000   2.180000  63.260000 ( 70.209942)
render     235.300000   8.080000 243.380000 (251.566731)
cleanup      0.390000   0.040000   0.430000 (  0.460767)
write        0.620000   1.250000   1.870000 (  2.747295)
こんな感じの表示が得られます。
renderの部分が実際に書くページのhtmlを作成してる所です。
ここでだいたい4分位かかってgenerateと合わせて5分もかかっています。。。
さらにgenerateを追っていってどのGeneratorモジュールが時間使ってるのかを見ると
GenerateTagsが40秒位で一番時間を使っていました。
(GenerateCategoriesが10秒くらい。)
renderの方は各ページ1秒未満程度で、さらに細かく何が時間かかってるか、
をBenchmarkで追うのは無理なので取り敢えずこんな所で。
まとめ
測ってみたところでここまでだと余りどうしようもないですが、 取り敢えずRubyでのBenchmarkの使い方と、 適当なモジュールの中を探ってBenchmarkを埋め込む方法のまとめ、というメモ。
