Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

CRubyコードリーディング(4) : ベンチマーク!

More than 5 years have passed since last update.

今回のテーマ

筆者がCRuby実装を読んでみようという記事です。第四回です。
CRuby本体にコミットを送ってみようとかいろいろしていた結果数日空きました。

今回はコードを掘るのではなくてCRubyのコードに対するベンチマークの取り方について。
必要に駆られてやったことなので、その記録もかねて。

benchmarkディレクトリ

CRubyのコードをpullして持ってくると、ルートにはbenchmarkディレクトリがあります。
なんだ、これを使えばよさそうですね。

中に入ると、いくらかの具体的なbenchamrk対象のrubyソースファイル(bm_xxxxxx.rb)にまぎれて、
run.rb, runc.rb, driver.rb
など起動に使えそうなそれっぽい物が。

これ叩けばよいのかな?と想像してmake installしたrubyバイナリで起動してみますと……

~/.rubydev/bin/ruby ./benchmark/run.rb

……。パーミッション関連のエラーが出ます。
contrib以下のファイルが読み込めていないようです。
いや、ファイルがないんですね。これは。

うーん。

灯台下暗し

そういえばMakefileからこういう操作はできてほしいです。そもそもそちらが基本なのではないかと思いました。

grep benchmark *.mk

とするとcommon.mkにbenchmarkルールが見つかりました。
またhelpルールも見つかりまして、make helpでその他のMakefileの用法もきれいに出力してもらえるのが分かりました。(ああ、これはすぐ試すべきだった。。。)

make golfなんていう興味深い物もあるのですが、ともかくmake helpでbenchmarkのことをしらべます。

<前略>
  :
  benchmark:       benchmark this ruby and COMPARE_RUBY
  :
<後略>

とのことで、「COMPARE_RUBY」と現在のrubyの比較を行うようですね。COMPARE_RUBYってなんでしょうか?
grep COMPARE_RUBY *.mkを見ると……

grep COMPARE_RUBY *.mk
common.mk:COMPARE_RUBY = $(BASERUBY)
common.mk:                  --executables="$(COMPARE_RUBY); built-ruby::$(RUNRUBY)" \
common.mk:                  --executables="$(COMPARE_RUBY); built-ruby::$(RUNRUBY)" \
common.mk:                  --executables="$(COMPARE_RUBY); built-ruby::$(RUNRUBY)" \
common.mk:      "  benchmark:       benchmark this ruby and COMPARE_RUBY" \
uncommon.mk:COMPARE_RUBY = $(BASERUBY)
uncommon.mk:                --executables="$(COMPARE_RUBY); built-ruby::$(RUNRUBY)" \
uncommon.mk:                --executables="$(COMPARE_RUBY); built-ruby::$(RUNRUBY)" \
uncommon.mk:                --executables="$(COMPARE_RUBY); built-ruby::$(RUNRUBY)" \
uncommon.mk:    "  benchmark:       benchmark this ruby and COMPARE_RUBY" \

これは環境変数参照ですね。つまるところ環境変数にCOMPARE_RUBYを設定して実行するだけで2つのバイナリ間で比較できそうですね!
バイナリ作りそのものはブランチごとに./configure --prefix=$HOME/.rubydev_origとかやってあげればできますからきっと簡単ですね!

画餅に帰す

COMPARE_RUBYに事前にビルドしておいた$HOME/.rubydev_orig/bin/rubyを設定して実行してみたところ問題無くベンチマークが実行され、結果がファイルとして書き出されました。

よし。中身を見てみましょう。
ん……?COMPARE_RUBYに設定したバイナリではなくて、システムのrubyがつかわれてしまっています。

簡単にできそうと思いましたがそんなことはなかった。。。
改めてMakefileのCOMPARE_RUBY該当行周辺を読んでみましょう。

COMPARE_RUBY = $(BASERUBY)

ん?COMPARE_RUBYは強制的に$(BASERUBY)に設定されていますね。これは書換えできないのでしょうか。
(実際にはあたふたいろいろしてしまいましたが)Makefileのmanページを読んでみることにしました。man make

<前略>
  :
       -e, --environment-overrides
            Give variables taken from the environment precedence over variables from makefiles.
  :
<後略>

makeは-eオプションをつけることで、内部で変数を設定する時、強制的に上書きができる、と。なるほど。

make benchmark -e COMPARE_RUBY=$HOME/.rubydev_orig/bin

今度こそ上手く動きました。

取ったベンチマークの分析は……頑張りましょう。

ベンチマーク手順・まとめ

  • 開発中のrubyの速度を計測したい場合はmake benchmarkが利用できる
    • 複数のrubyをインストールするには./configure --prefixを普通に使えばよいので、任意のブランチ間の差を見たければこれを使う。
    • この時COMPARE_RUBYを環境変数で、比較対象のruby実行バイナリを設定しておけば、2つの速度比を測ることができる
      • ただしMakefileの中で上書きされるので、makeの-eオプションを使い強制的に設定しなければ動作しない。
shiracha
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away