この記事ではruby 2.2.3とrustc 1.4.0を使用しています。
すごい要約
-
- RubyからGoの関数をつかう → はやい – Qiita
- Crystalで書く → はやい – Qiita
とのことです。
Rust、はやい
最初にRubyとRustの計算速度を比べるため、フィボナッチ数を単純に計算するやつをそれぞれ書きました。
def fib(n)
return n if n <= 1
fib(n - 1) + fib(n - 2)
end
puts fib(40)
fn fib(n: u32) -> u32 {
if n <= 1 {
n
} else {
fib(n - 1) + fib(n - 2)
}
}
fn main() {
println!("{}", fib(40));
}
実行結果は以下です。
$ time ruby fib.rb
102334155
real 0m12.538s
user 0m12.462s
sys 0m0.047s
$ time cargo run
102334155
real 0m1.468s
user 0m1.398s
sys 0m0.063s
$ time ./target/release/fib
102334155
real 0m0.517s
user 0m0.514s
sys 0m0.002s
この処理だとRustの方がはやいようです。
Rustを共有ライブラリにする
RustをShared LibraryとしてコンパイルしてRubyから呼ぶために以下の変更を加えます。
#[no_mangle]
pub extern fn fib(n: u32) -> u32 {
if n <= 1 {
n
} else {
fib(n - 1) + fib(n - 2)
}
}
[lib]
name = "fib"
crate-type = ["dylib"]
ビルドします。
$ cargo build --release
target/release 以下に libfib.dylib が生成されていたら成功です。
RubyからRustの関数を呼ぶ
事前に ffi をインストールしてください。
require "ffi"
module Fib
extend FFI::Library
ffi_lib 'target/release/libfib.dylib'
attach_function :fib, [:uint], :uint
end
puts Fib.fib(40)
Ruby meets Rust
速度の計測です。
RubyRuby + RustRuby + Go13.311s0.629s0.725s13.262s0.639s0.723s13.621s0.621s0.720s
どの言語も仲良くやっていくのが平和でよいなと思いました。