先日、ElixirからRustのプログラムを呼び出してフィボナッチ数の計算を高速化してみたので、今度はRubyを高速化してみます。

環境

  • マシン

    • Microsoft Windows 10 Home
    • Intel64 Family 6 Model 78 Stepping 3 GenuineIntel ~2300 Mhz
    • 3,935 MB
  • Ruby

    • ruby 2.3.1p112 (2016-04-26 revision 54768) [x64-mingw32]
  • Rust

    • rustc 1.9.0 (e4e8b6668 2016-05-18)
    • cargo 0.10.0-nightly (10ddd7d 2016-04-08)

検証したソースコード

Elixirの時同様、どちらの言語もまだまだ初学者レベルなので、細かいところがおかしい場合はご指摘願います。 また、「こうした方が早くなる」等のアドバイスも非常に助かりますので、お時間があればご教示願います。

fibonacci.rb

require "ffi"
require benchmark

module Fib
  extend FFI::Library
  ffi_lib lib/fib.dll
  attach_function :fib, [:uint], :uint
end

def fibonacci(n)
  return n if n <= 1
  fibonacci(n - 1) + fibonacci(n - 2)
end

0.upto(ARGV[0].to_i) do |num|
  ruby_result = Benchmark.realtime do
    fibonacci(num)
  end
  rust_result = Benchmark.realtime do
    Fib.fib(num)
  end
  puts format("%2d, %.9f, %.9f", num, ruby_result, rust_result)
end

lib.rs

#[no_mangle]  //関数名をマングリングさせないようにする
pub extern fn fibonacci(n: u32) -> u32 {
    match n {
        0 => 0,
        1 => 1,
        _ => fibonacci(n-1) + fibonacci(n-2)
    }
}

Cargo.toml

[package]
name = "fib"
version = "0.1.0"
authors = ["k-masatany"]

[dependencies]

[lib]
name = "fib"
crate-type = ["dylib"]

rustはreleaseで最適化してビルドしています。

結果

f:id:k_masatany:20160801230259p:plain * 画像が大きすぎて文字がつぶれました。青い棒がRubyのみ、赤い棒(見にくい)がRust呼び出し版です。

まとめ

  • Rubyはとても書きやすい。Rustは少しレベルアップしました?(マッチング使ってみました)
  • やっぱりRustはやい。