プログラムのコードを書き換えずにRubyプログラムをStackprof付きで実行する、stackprof-run というGemを作りました。
こんにちは。 id:Pocke です。 Stackprofを便利に使うGemを作成したので紹介しようと思います。
Stackprof とは
下記参照
Stackprof を使う際の問題点
コマンドラインツールに対してStackprofを使用する際、通常だと以下のようなコードを対象となるプログラムに追加しなければいけません。
StackProf.run(mode: :cpu, out: 'stackprof-out') do # ここに元からあるメインとなる処理が入る end
そのため、対象のプログラムをプロファイリングするためには上記のコードを埋め込んだ上でインストールして実行する必要が出てきます。
この作業は煩わしく、またインストールしたのを忘れて意図せずStackprofつきでコマンドを実行してしまうこともあります。
手元に入っているRuboCop、ときによっていきなりASTをputsしたりpryが走ったりstackprofの結果を吐いたり突然Exception吐いたりするから信用ならない(デバッグ用にインストールしたやつをそのままにしてしまう
— Pocke (@p_ck_) 2016年12月22日
stackprof-run
という解決策
stackprof-run
を使用すると、上記の問題が解決されます。
まずは、stackprof-run
gem をインストールします。
$ gem install stackprof-run
使い方は至って簡単で、解析対象のコマンドの前にstackprof-run
を前置するだけです。
# 例えば、rubocop --only Style/AlignHash というコマンドをstackprofで計測したい場合 $ stackprof-run rubocop --only Style/AlignHash
これだけで、RuboCopがstackprofの解析つきで実行されます。便利。
解説
stackprof-run
のコードは非常に短く、以下の21行だけです。
#!/usr/bin/env ruby cmd = ARGV.shift path = `which #{cmd}`.chomp $PROGRAM_NAME = cmd mode = ENV['STACKPROF_MODE']&.to_sym || :cpu out = ENV['STACKPROF_OUT'] || 'stackprof-out' require 'stackprof' ex = nil StackProf.run(mode: mode, out: out) do begin load path rescue Exception => ex end end raise ex if ex
やっていることも単純で、Stackprofのブロックの中で、渡されたコマンドのスクリプトファイルをロードしているだけです。
上のコードが全てですが、気になる方がいたらREADMEも読んでみて下さい。
作ろうと思ったきっかけ
なるべくこうならないように、困った時の QA ツールを別途充実させる方針をとってる https://t.co/xi31slrQ6s https://t.co/6hPiBv3G2j
— Kuniwak@久しぶりの休み (@orga_chem) 2016年12月22日