今日は、RubyMotion でベンチマークを計測してみたいなと思い、いろいろ試行錯誤していました。Ruby には benchmark というライブラリがあるのでそれを使えばすぐなのですが、RubyMotion ではライブラリがないので自作することにしました。そして、Objective-C を使って書いておけば何かの役に立ちそうかと簡単なライブラリをつくりました。
興味を持たれた方は Github に置いてありますので、
1 2 3 | |
と実行してください。
以下は試行錯誤の過程です。
RubyMotion Project Management Guide を読むと、サードパーティのライブラリは vendor ディレクトリを作成しそこに配置するのが慣わしらしいです。
配置するライブラリは Xcode で Cocoa Touch Static Library のテンプレートを選択して別途用意し、vendor ディレクトリに配置します。そして、Rakefile にライブラリを設定します。
1 2 3 4 5 6 7 8 9 10 11 | |
app.vendor_project でライブラリのパス、ライブラリの種類(:xcode か :static)、ヘッダファイルが存在するディレクトリを :headers_dir で設定します。:headers_dir は第一引数で指定したライブラリのパスからの相対パスで指定します。
:headers_dir は必ず指定した方がよさそうです。MacRuby や RubyMotion では、ヘッダファイルを解析して、どのような定数があるか、メソッドに Blocks が使われていないかチェックし、MacRuby や RubyMotion でそれらが使用できるようにするために Bridge Support というファイルを作ります。実際にプロジェクトをビルドしていただくと vendor/Benchmark/Benchmark.bridgesupport と Bridge Support ファイルが作成されています。
ライブラリは、
1 2 3 | |
のように使用し、b.bm = lambda { 1 + 2 + 3 } で Blocks を property として受け付けるように Objective-C でライブラリを作成しています。
MacRuby や RubyMotion では、lambda などで生成した Proc オブジェクトを Blocks として実行することができます。
パフォーマンスを計測するたびに、毎回、上記のように記述するのが煩わしいので、vendor/Benchmark/lib/Benchmark.rb で
1 2 3 4 5 6 7 8 9 | |
というラッパーを用意してあります。bm メソッドの引数でもらうブロックは Proc オブジェクトなので、そのまま Blocks として使っています。
1 2 3 4 | |
と記述できるようなります。
Github にアップロードしたプロジェクトを実行すると、以下のようになります。
1 2 3 4 5 6 7 | |