Skip to content

ymnao/ruby-jit-bench

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

14 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ruby-jit-bench

Ruby の JIT コンパイラ(YJIT / ZJIT)のアーキテクチャ差を可視化するベンチマーク集。

RubyKaigi 2026 LT「RubyのJITはテスト勉強に似ている」実証実験用。

コンセプト

  • YJIT = 過去問ガチ勢(LBBV: 型特化した基本ブロックを逐次コンパイル)
  • ZJIT = 教科書全理解勢(SSA HIR: メソッド全体を最適化パス付きでコンパイル)

実行

make all          # 全ベンチマーク + コンパイル統計
make bench        # 速度比較のみ(5回計測の中央値)
make stats        # コンパイル統計のみ
make hir          # ZJIT HIR 最適化前後の比較
make full         # bench + stats + hir すべて

# 計測回数を変更する場合
BENCH_ITER=3 make bench

ベンチマーク一覧

基本ベンチマーク

ファイル 何を測るか 有利なJIT
type_stable.rb 型安定ループ(Integer演算) YJIT
polymorphic.rb 多態ディスパッチ(5クラス) YJIT
recursive.rb 再帰呼び出し(fib30) 要実測(ZJIT有利の報告あり)

ZJIT アーキテクチャ検証ベンチマーク

ファイル 何を測るか ZJITの最適化 備考
ivar_heavy.rb ivar冗長読み出し load-store 最適化(冗長 LoadField 除去) Ruby HEAD で効果大
setivar.rb ivar連続代入 Dead Store Elimination(PR #16507、開発中) Rails at Scale 記事では ZJIT 2ms vs YJIT 5ms(当時の Ruby HEAD 依存、現ビルドでは再現しない場合あり)
constant_fold.rb 定数畳み込み・DCE fold_constants + eliminate_dead_code SSA-IRでデータフロー解析
frozen_const.rb frozenオブジェクトのivar読み frozen LoadField → Const 変換 コンパイル時に値確定
c_method_inline.rb Cメソッドインライン化 Integer#succ → FixnumAdd命令 後続の最適化パスと連鎖

HIR 最適化比較

make hir で ZJIT の最適化パイプラインの before/after を確認できる。

# 個別に確認する場合(デフォルト閾値でプロファイルデータを十分に収集)
ruby --zjit --zjit-dump-hir-init -e "def add(a,b); a+b; end; 100.times{add(1,2)}"
ruby --zjit --zjit-dump-hir -e "def add(a,b); a+b; end; 100.times{add(1,2)}"

ZJIT 最適化パスの実行順序

  1. type_specialize — 型プロファイルに基づく特殊化
  2. inline — 軽量メソッドのインライン化
  3. optimize_getivar — ivar読み込みの最適化
  4. optimize_c_calls — Cメソッド呼び出しの最適化
  5. convert_no_profile_sends — プロファイルなし送信の変換
  6. optimize_load_store — 冗長な LoadField の除去
  7. fold_constants — 定数畳み込み
  8. clean_cfg — 制御フローグラフの整理
  9. remove_redundant_patch_points — 冗長なパッチポイントの除去
  10. remove_duplicate_check_interrupts — 重複割り込みチェックの除去
  11. eliminate_dead_code — デッドコード除去

これが「教科書全理解勢」のアプローチ。YJIT(LBBV)にはこのようなパイプラインがなく、基本ブロック単位で型特化コードを直接生成する。

Ruby HEAD の推奨

Ruby 4.0.2 時点では ZJIT の多くの最適化が未搭載。Ruby HEAD からビルドすることを強く推奨

Ruby HEAD(ruby/ruby master)にのみ存在する主要最適化:

  • load-store 最適化(冗長な LoadField の除去)
  • Lightweight Frames(JIT-to-JIT呼び出しで最大4.9%高速化)
  • ポリモーフィック getivar
  • no-profile send 再コンパイル
  • --zjit-dump-hir-iongraph(Iongraph ビューア用JSON出力)
# Ruby HEAD のビルド(rbenv)
rbenv install ruby-dev
rbenv local ruby-dev

Iongraph 可視化(Ruby HEAD のみ)

ruby --zjit --zjit-dump-hir-iongraph script.rb
# /tmp/zjit-iongraph-{PID}/ に JSON 出力
# → https://mozilla-spidermonkey.github.io/iongraph/ で表示

補足

  • Ruby 4.0.2 時点では多くのベンチマークで YJIT が優勢。ZJIT の load-store 最適化や DCE はまだ発展途上
  • Rails at Scale の setivar ベンチマーク では ZJIT 2ms vs YJIT 5ms という結果が報告されている(2026年3月時点の Ruby HEAD。ビルドにより結果は異なる)
  • 再帰 fib30 では ZJIT が YJIT より約60%高速 という報告あり(RubyKaigi 2025 発表時点。現ビルドでは再現しない場合がある)
  • エスケープ解析+スカラー置換(PR #16096、クローズ済み)、Dead Store Elimination(PR #16507)が開発中

環境

  • Ruby 4.0.2(rbenv)/ Ruby HEAD 推奨
  • macOS ARM64
  • 外部 gem 不要

参考

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors