macOS 上で Ruby のパフォーマンスを計測する

(追記 2017-10-02 01:28:42 +0900) Xcode 9 からは以下のように計測に失敗するようです。解決策が見つかるまでは Xcode 8.3 を使うか、Instruments.app で直接計測する必要がありそうです。

$ iprofiler -timeprofiler ./a.out
iprofiler error: DTPerformanceSession: Authorization failure.

macOS では、ターミナルから iprofiler を経由してコマンドを実行することでパフォーマンスを計測することができる。

$ iprofiler -timeprofiler ./a.out
iprofiler: Preparing recording resources
iprofiler: Profiling process 66908 (a) for 10 seconds
iprofiler: Target pid has died. Ending recording.
iprofiler: Saving session...
iprofiler: Session saved at /Users/watson/tmp/a.dtps

実行すると a.dtps というファイルができるので、ターミナルで open a.dtps と実行するか Instruments.app で開く。

Ruby のパフォーマンスを計測する場合には以下のように実行する。最初にテスト用のコードを用意しておく。

$hash1 = {}
1000.times { |i| $hash1[i.to_s] = i }
$hash2 = {}
1000.times { |i| $hash2[(i*2).to_s] = i*2 }

5000000.times do
  $hash1 == $hash2
end
$ iprofiler -timeprofiler /usr/bin/ruby bench.rb
iprofiler: Preparing recording resources
iprofiler: Profiling process 67727 (ruby) for 10 seconds
iprofiler: Target pid has died. Ending recording.
iprofiler: Saving session...
iprofiler: Session saved at /Users/watson/tmp/ruby.dtps

どうやら実行ファイルを /usr/bin/ruby のように絶対パスで指定しないとエラーになるようだ。

$ iprofiler -timeprofiler ruby bench.rb
iprofiler error: 'ruby' cannot be launched

計測結果は以下のような感じで表示されるが、シンボルが見つからないものはアドレス番地が表示されるだけ。 170306-0001.png (648.1 kB)

Rubyソースコードをダウンロードして自前でビルドするとずいぶん見栄えが良くなる。

$ iprofiler -timeprofiler ./miniruby ~/tmp/bench.rb

170306-0005.png (591.0 kB)

関数名部分をクリックすると、ソースコードを見ながらどの部分が実行に時間がかかっているかわかる。

170306-0006.png (485.8 kB)

以下のアイコンをクリックすると表示を切り替えることができる。 instruments-icons.png (24.0 kB)

アセンブリも表示すると以下のようになる。 170306-0007.png (931.9 kB)