ユニファ開発者ブログ

ユニファ株式会社プロダクトデベロップメント本部メンバーによるブログです。

Ruby 3.3 で YJIT 有効化しました!

こんにちは、サーバーサイドエンジニアの横山です。

前回はRuby / Rails バージョンアップ に関する記事を書きましたが、今回はバージョンアップリリース後に行った YJIT 有効化 に関してまとめさせていただきます! tech.unifa-e.com

YJIT 導入背景

YJIT は、Ruby の JIT コンパイラの一つで、Ruby 3.2 以降で安定版として利用可能になりました。
Ruby 3.3 では導入が簡単になっただけでなく、メモリの効率化やパフォーマンス向上といった大きな改善がされたため、今回のバージョンアップにあわせて導入しました。

www.ruby-lang.org

導入環境

  • Ruby 3.3
  • Rails 7.0

有効化の方法

YJIT を有効にするには、以下の3種類の方法があります。

  1. config/initializers/enable_yjit.rbRubyVM::YJIT.enable を記述
  2. 環境変数RUBYOPT--yjit--yjit-exec-mem-size 等のYJIT関連のオプションを設定
  3. Rails7.2 以降 + Ruby3.3 以降の組み合わせにする(デフォルトで YJIT が有効になります)

今回は、メモリ使用率の増加を考慮し、環境変数RUBYOPT--yjit-exec-mem-size=32 を指定する形で有効化しました。

事前検証

YJIT 有効化によって、 CPU 使用率やレスポンス速度の向上が見込まれる一方で、メモリ使用率の増加が懸念されました。
そのため、ステージング環境にて、処理負荷の大きい API リクエストを一定量実行し、メモリの使用率の増加などの観点で有効化前後の比較を行いました。

以下、結果の表です。

項目 有効化前 有効化後 差分 割合変化
CPU 使用率 30% 25% ▼5% 約 16% 減少
メモリ使用率 50% 62% ▲12% 約 24% 増加
Target ResponseTime 0.45s / 0.36s 0.35s / 0.35s ▼0.1s / ▼0.01s

CPU 使用率やレスポンスタイムに一定の改善が見られた一方で、メモリ使用量は明確に増加していることがわかりました。
そのため、本番環境ではYJITのメモリ使用量の制限 --yjit-exec-mem-size=32 を設定することにしました。

本番環境での結果

  • 有効化リリース日:2025年4月23日
  • 比較期間:有効化1ヶ月前〜有効化3ヶ月後まで
    (時期によってアプリケーションのリクエスト数等も大きく変わる可能性があるため、有効化後は3ヶ月間の期間で比較しました)

  • CPU 使用率(平均値)

  • メモリ 使用率(平均値)

グラフからの概算になりますが、ピーク時の平均値を比較すると、以下のような結果となりました。

項目 有効化前(〜4/23) 有効化後(4/23〜) 差分 割合変化
CPU 使用率 30〜40% 25〜30% ▼約5% 約 16% 減少
メモリ使用率 23〜28% 25〜32% ▲約2〜4% 約 8~14% 増加

CPU 使用率については、YJIT 有効化後から1週間ほど経過後に、負荷ピーク時の使用率が上がった期間もありますが、結果として約 16% 減少程度の改善が確認できました。

メモリ使用率については、約2〜4%の絶対値の増加に相当し、割合としては約 8 ~ 14 %の上昇となっています。 ステージング検証ほど上昇はしていないですが、YJIT 有効化によってメモリ使用量が上がったことが明確で、パフォーマンス向上した一方で、メモリ負荷が増加していることが分かります。

API のレスポンスタイム

本番環境では、Target ResponseTime ではなく、処理負荷が比較的重めの4種類のAPIリクエストについて、一定量実行したレスポンスタイム - DB処理時間の平均値を計測しました(各リクエストの回数は同一です)。

API リクエスト 有効化前(ms) 有効化後(ms) 減少量 (ms) 減少率 (%)
A パターン 216.0597 207.9133 ▼8.1464 3.77%
B パターン 223.4597 176.3601 ▼47.0996 21.07%
C パターン 174.1359 172.2695 ▼1.8664 1.07%
D パターン 175.0646 165.3388 ▼9.7258 5.56%

元々処理時間がそれほど長くないこと、またリクエスト内容やタイミングの影響もあり、減少したと明確に言い切ることは難しいですが、 全体的には処理速度が向上している傾向が確認できました。

まとめ

検証結果から、予想通り全体のCPU負荷が軽減された一方で、 メモリ使用量が増加したことが確認できました。

今後は、--yjit-exec-mem-size の値を拡張した際の効果なども検証してみたいと考えていますが、検証期間中は他の機能リリースや改善も重なっていたこと、DB 処理や他のサービスへのリクエストなど純粋なRuby処理以外の影響もあり、YJIT による改善を正確に測定することは難しいため、課題として残ります。

現在チームでは Ruby 3.4 / Rails 8.0 へのバージョンアップも進行中です。 Ruby 2.5 / Rails 5.2 から始まったバージョンアップですが、とうとう最新バージョンまでアップデートできそうで、本当に良かったです!


ユニファでは一緒に働く仲間を募集しています! jobs.unifa-e.com