K.Sasada's Home Page

Ruby 遊び / 拡張 C ライブラリを作ってみる

って?

Ruby は、比較的簡単に C による拡張ライブラリが作れるらしいです。

拡張ライブラリというのは、要するに、Ruby から呼べる機械語のメソッド郡と考えていいんじゃないかと思います。つまり、Ruby だと処理速度がどうしても気になってしまう一部のクリティカルセクションを、これにより機械語で書き換える、ということができます。

というわけで、どれくらい簡単か、やってみましょう。

Ruby 本に従って、次の C プログラムを書きました。


#include "ruby.h"

VALUE test(int n){
  volatile int i;
  for(i=0;i<(FIX2INT(n));i++){
  }
  return Qnil;
}

Init_test(){
  rb_define_global_function("test",test,1);
}

ruby で書けばこんな感じの処理。

def test n
  n.times{}
end

はい。とても単純でいいかげんで意味がないですが、まぁいいです。気にしないこと。

で、これからきっと面倒なことが、例えば makefile の準備だとか、そういうのがあると思うんですが。

ruby -r mkmf -e 'create_makefile("test")'
nmake # ruby / mswin 版なので

これで、おしまい。拡張ライブラリ test.so が出来上がってます。いや、まぢで。

確認

なんか、拍子抜けするほど簡単ですが。(というか、簡単な例しか作ってないですけど)

テストします。ついでに性能も。

require 'test' # 拡張ライブラリをロードするために必要になる
require 'benchmark'

CO = 0x3ffffff

puts Benchmark.measure{
  CO.times{}
}

puts Benchmark.measure{
  test(CO)
}

実行結果

 17.828000   0.000000  17.828000 ( 17.875000)
  0.078000   0.000000   0.078000 (  0.078000)

というわけで、実行されていることがわかります。

いやー、やっぱ速いねぇ。さすが機械語。一応アセンブラリストで確認したし、i を volatile にしたので、ループが削れてるってこたないです。

まとめ

Ruby がいかに簡単に C で書かれた何かを利用しやすいかどうか、というか、そのとっつきやすさを実感できました。多分。

本気でやるには、例えばもっと Ruby のデータに対して何か突っ込んだことをしなければならないので、やっぱり面倒くさいのかもしれないんですが、まぁ、はじめの一歩としては、非常にやりやすいものでありました。

今度、なんか作ってみるかなぁ。なんかネタあったかなぁ・・・。

Sasada Koichi / sasada@namikilab.tuat.ac.jp
$Date: 2003/04/28 10:27:52 $