この記事では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

どの言語も仲良くやっていくのが平和でよいなと思いました。

广告
将在 10 秒后关闭
bannerAds