Edited at

TruffleRubyを動かしてみた

More than 1 year has passed since last update.

RubyKaigi 2018でも発表のあったらしいOracle製の高速Ruby実装「TruffleRuby」を動かしてみた。

最初はこちらの記事と同じようにやろうとしたけど、Mac上でDockerイメージのビルドがうまくいかなかったので、公式ドキュメントを参考にAmazon Linux上で直に動かしてみた。

[追記]

gem install nokogiriしようとしたら「LLVMが必要だ」と言われて、yum install llvm clangしたもののunsupported clang version: 3.6.2。やっぱり公式にサポートされているディストリビューションを使ったほうがよさそう。


公式ドキュメントより


  • Community Edition


    • Linuxのみ

    • productionで使ってもOK



  • Enterprise Edition


    • LinuxとMac両方あり

    • 評価だけならタダだけど本番で使っちゃダメ

    • Oracle Technology Networkからダウンロードする



アクティブにテストされている環境:


  • Oracle Linux 7

  • Ubuntu 16.04 LTS

  • Fedora 25

  • macOS 10.13

LLVM, zlib, libsslが必要。ロケールはUTF-8にする必要がある。

と書いてあるが、今回の手順を試すだけならLLVMはなくても動いた。

ロケールはja_JP.UTF-8にした。


TruffleRubyのセットアップ

export LANG=ja_JP.UTF-8

wget https://github.com/oracle/graal/releases/download/vm-1.0.0-rc2/graalvm-ce-1.0.0-rc2-linux-amd64.tar.gz

tar xf graalvm-ce-1.0.0-rc2-linux-amd64.tar.gz

cd graalvm-ce-1.0.0-rc2/bin

./gu install org.graalvm.ruby

# benchmark-ipsのインストールのために必要
sudo yum install -y openssl openssl-devel

# hoge.rbで使っているのでインストール
./gem install benchmark-ips

[ec2-user@ip-10-4-1-235 bin]$ ./ruby --version

truffleruby 1.0.0-rc2, like ruby 2.4.4, GraalVM CE Native [x86_64-linux]


hoge.rb

#!/usr/bin/env ruby

require 'benchmark/ips'

def call
i = 0
while i < 1000
i += 1
end
end

call; call; call; call; call # JITを効かせたいがために複数回呼び出す

Benchmark.ips do |x|
x.report('call') { call }
x.compare!
end


TruffleRubyでベンチマーク実行:

[ec2-user@ip-10-4-1-235 bin]$ ./ruby hoge.rb

Warming up --------------------------------------
call 91.374k i/100ms
Calculating -------------------------------------
call 1.858M (±12.7%) i/s - 8.955M in 5.038041s


比較のため、普通のCRuby 2.4をインストール

sudo yum install -y ruby24

sudo update-alternatives --set ruby /usr/bin/ruby2.4

[ec2-user@ip-10-4-1-235 bin]$ /usr/bin/ruby --version

ruby 2.4.4p296 (2018-03-28 revision 63013) [x86_64-linux-gnu]

CRuby 2.4でベンチマーク実行:

[ec2-user@ip-10-4-1-235 bin]$ /usr/bin/ruby hoge.rb

Warming up --------------------------------------
call 4.736k i/100ms
Calculating -------------------------------------
call 48.834k (± 0.4%) i/s - 246.272k in 5.043175s

8955 / 246.272 = 36.5だから、確かに37倍速かった。