Go to list of users who liked
Share on X(Twitter)
Share on Facebook
More than 5 years have passed since last update.
この記事ではRuby2.2.3とGo1.5.1を使用しています。
すごい要約
Go and Ruby-FFI - Code7 Interactiveを読むといい。
Go、はやい
最初にRubyとGoの計算速度を比べるため、フィボナッチ数を単純に計算するやつをそれぞれ書きました。
deffib(n)returnnifn<=1fib(n-1)+fib(n-2)endputsfib(40)packagemainimport"fmt"funcfib(nuint)uint{ifn<=1{returnn}returnfib(n-1)+fib(n-2)}funcmain(){fmt.Println(fib(40))}比較のためにできるだけ単純に同じロジックで実装しました。
実行結果は以下です。
> time ruby fib.rb102334155ruby fib.rb 19.00s user 0.11s system 92% cpu 20.690 total> time go run fib.go102334155go run fib.go 1.24s user 0.25s system 84% cpu 1.758 total> time ./fib102334155./fib 0.80s user 0.01s system 89% cpu 0.903 totalこの処理だと圧倒的にGoの方がはやいようです。
「Rubyより、ずっとはやい!!!!!!」
Goを共有ライブラリにする
GoをRubyから利用するためには、まずShared Libraryとしてコンパイルします。
ここらへんは「Golang で Shared Library を出力する。」を参考にさせていただきました。
Goのビルド時に-buildmode=c-sharedオプションを渡すとよしなにしてくれます。
ただ、今のままだとRubyから関数が呼べないのでGoのソースを書き換えます。
packagemainimport"C"//export fibfuncfib(nuint)uint{ifn<=1{returnn}returnfib(n-1)+fib(n-2)}funcmain(){}ポイントはCをインポートするのと、//export fibを追記する点です。
Rubyから呼べる関数を明示的に選べます。main()は実行されませんが、コンパイル上必要なので書いておきます。
これで
> go build -buildmode=c-shared -o fib.so fib.gofib.so と fib.h がディレクトリに作成されたら成功です。
RubyからGoの関数を呼ぶ
共有ライブラリとしてコンパイルしたGoをRubyから扱うにはFFIを使用します。
そもそもFFIとはForeign function interfaceの略で、ffiというgemがこれをRubyでもいい感じにやるぞ!ってやつです。
まずインストール。
> gem install ffiRuby-FFIはRubyのオブジェクトに他言語の関数をアタッチしていく感覚で使用します。
require"ffi"moduleFibextendFFI::Libraryffi_lib"fib.so"attach_function:fib,[:uint],:uintendputsFib.fib(40)このattach_function()の引数は、「関数名、[関数の引数型]、戻り値型」です。
ちなみに型として利用できるのはTypes · ffi/ffi Wikiに一覧があります。
今回は数値だったのでそこまで問題はありませんが、文字列をやりとりする場合は、
Goの関数内で受け取ったCのstringをC.GoString(str)としたり、逆にGoのstringをC.CString("Go no string dayo!!!!!")
するなど適宜変換してあげる必要があります。
詳しくはcgo - The Go Programming Languageを参照!!!
Ruby meets Go
はいここまで長かった!
速度の計測です。
> time ruby fib.rb102334155ruby fib.rb 19.00s user 0.11s system 92% cpu 20.690 total> time ruby go-fib.rb102334155ruby go-fib.rb 0.85s user 0.06s system 95% cpu 0.953 total約20倍はやい!!!!!!すごい!!!!!!!!!!!!!!
Go単体での実行に毛が生えた程度になりました!!!!!!!!!!!!!!!!!!
もう「Rubyより、ずっとはやい」なんて言わせないぞ!!!!!!!!
こうやってそれぞれの得意分野でよろしくやっていくのが平和でよいなと思いました。
参考
Golang で Shared Library を出力する。 - Qiita
ffi/ffi
cgo - The Go Programming Language
Go and Ruby-FFI - Code7 Interactive
Register as a new user and use Qiita more conveniently
- You get articles that match your needs
- You can efficiently read back useful information
- You can use dark theme