pockestrap

Programmer's memo

プログラムのコードを書き換えずにRubyプログラムをStackprof付きで実行する、stackprof-run というGemを作りました。

github.com

こんにちは。 id:Pocke です。 Stackprofを便利に使うGemを作成したので紹介しようと思います。

Stackprof とは

下記参照

github.com

Stackprof を使う際の問題点

コマンドラインツールに対してStackprofを使用する際、通常だと以下のようなコードを対象となるプログラムに追加しなければいけません。

StackProf.run(mode: :cpu, out: 'stackprof-out') do
  # ここに元からあるメインとなる処理が入る
end

そのため、対象のプログラムをプロファイリングするためには上記のコードを埋め込んだ上でインストールして実行する必要が出てきます。

この作業は煩わしく、またインストールしたのを忘れて意図せずStackprofつきでコマンドを実行してしまうこともあります。

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も読んでみて下さい。

作ろうと思ったきっかけ