LoginSignup
41

More than 5 years have passed since last update.

posted at

updated at

RubyからRustの関数をつかう → はやい

この記事ではruby 2.2.3とrustc 1.4.0を使用しています。

すごい要約

とのことです。

Rust、はやい

最初にRubyとRustの計算速度を比べるため、フィボナッチ数を単純に計算するやつをそれぞれ書きました。

fib.rb
def fib(n)
  return n if n <= 1
  fib(n - 1) + fib(n - 2)
end

puts fib(40)
main.rs
fn fib(n: u32) -> u32 {
    if n <= 1 {
        n
    } else {
        fib(n - 1) + fib(n - 2)
    }
}

fn main() {
    println!("{}", fib(40));
}

実行結果は以下です。

Ruby
$ time ruby fib.rb
102334155

real    0m12.538s
user    0m12.462s
sys     0m0.047s
Rust
$ time cargo run
102334155

real    0m1.468s
user    0m1.398s
sys     0m0.063s
ビルド済みRust
$ time ./target/release/fib
102334155

real    0m0.517s
user    0m0.514s
sys     0m0.002s

この処理だとRustの方がはやいようです。

Rustを共有ライブラリにする

RustをShared LibraryとしてコンパイルしてRubyから呼ぶために以下の変更を加えます。

lib.rs
#[no_mangle]
pub extern fn fib(n: u32) -> u32 {
    if n <= 1 {
        n
    } else {
        fib(n - 1) + fib(n - 2)
    }
}
Cargo.toml
[lib]
name = "fib"
crate-type = ["dylib"]

ビルドします。

$ cargo build --release

target/release 以下に libfib.dylib が生成されていたら成功です。

RubyからRustの関数を呼ぶ

事前に ffi をインストールしてください。

rust-fib.rb
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

速度の計測です。

Ruby Ruby + Rust Ruby + Go
13.311s 0.629s 0.725s
13.262s 0.639s 0.723s
13.621s 0.621s 0.720s

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

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
41