あるWebアプリケーションの Ruby on Rails のバージョンを7.1.3
に上げました。 Ruby のバージョンを3.3.0
に上げました。
ついでにYJITを有効にしました。
Enable YJIT · pubannotation/pubannotation@f9284cd
次のファイルを追加しました。
if defined? RubyVM::YJIT.enable
Rails.application.config.after_initialize do
RubyVM::YJIT.enable
end
end
運用中に何かの理由で無効にしたくなったら、コメントアウトするかファイルごと削除します。
この方法は、最新のRuby on Railsに取り込まれているそのままです。
YJITとは
Rubyを高速に実行する機能です。Ruby 3.3 から Ruby on Rails に適用するのも実用的になったそうです。次の記事で詳しく説明されています。
Ruby 3.3 YJITのメモリ管理とRJIT 〜すべてが新しくなった2つのJITを使いこなす | gihyo.jp
RubyはJust-In-Time(JIT)コンパイラという機能を備えており、これを有効化すると実行時に機械語を生成して様々な最適化が行なわれ、実行が高速になります。Ruby 3.3にはYJITとRJITという2つのJITコンパイラがあり、デフォルトでは無効になっていますが、それぞれ--yjitと--rjitで有効化できます。
Ruby on Rails では Ruby のオプションではなく、イニシャライザでYJITを有効にします。
この理由も説明されています。
Ruby 3.3ではRubyコード内でRubyVM::YJIT.enableを呼び出すだけでYJITが有効化できるようになりました。
これを使ってYJITの起動を遅延させることで、アプリ初期化後は使われないコードのコンパイルを避けメモリ消費量を削減できます。Railsのイニシャライザから使うだけでも効果はあります
JITとは
プログラミング言語を高速に実行するテクニックの一つです。
ChatGPTは次のように説明します。
「JITコンパイル」(Just-In-Timeコンパイル)は、プログラムを実行する直前にコードをコンパイル(翻訳)する技術です。通常のコンパイル手法と異なり、プログラム実行時にコードの一部を動的にコンパイルします。これにより、実行時のパフォーマンスが向上する可能性があります。
原理
- 動的コンパイル: プログラム実行中に必要に応じてコードを機械語に変換します。
- 最適化: 実行時のデータや使用頻度の高いコードを分析し、最適化します。
- 遅延コンパイル: 使用されるまでコードのコンパイルを遅らせることで、必要な部分のみをコンパイルし、リソースの節約につながります。
効果
- パフォーマンス向上: 実行時の情報を利用して最適化するため、パフォーマンスが向上することがあります。
- プラットフォームの独立性: 中間言語を使用することで、異なるプラットフォーム間での互換性が高まります。
デメリット
- 初回実行の遅延: コンパイルが実行時に行われるため、初回の実行が遅くなることがあります。
- リソース消費: 実行時のコンパイルには追加のリソース(CPUやメモリ)が必要です。
- 最適化の複雑さ: 効果的な最適化を行うためには高度な技術が必要です。
実用例
- Java Virtual Machine (JVM): JavaのプログラムはJVM上で実行され、JITコンパイラによって最適化されます。
- .NET Framework: Microsoftの.NET言語は中間言語で書かれ、実行時にJITコンパイルされます。
- JavaScriptエンジン: 多くの現代のブラウザでは、JavaScriptコードはJITコンパイルを通じて高速化されます。
JITコンパイルは、実行時のパフォーマンス向上という大きなメリットがある一方で、初回実行の遅延や追加リソースの必要性などのデメリットも存在します。
感想
手動で動作確認をした感じでは、キビキビ動くようになった気がします。
しかし、JITが起動直後から効くとは思えません。プラシーボ効果だと思います。