RubyのJITコンパイラを理解したい！rubykaigiの香りを添えて

# まえがき (ポエムなので読み飛ばせます)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423146/bd50e958-7747-d67c-2009-b585d225dc90.png)

「Rubyは遅い！」と言われがちですが、来たる Ruby3.0 に向けて、今までよりも3倍の高速化を図る試み、 ` Ruby 3x3`が進行しています。
先月行われたrubykaigi2019でもその取り組みが発表され、多くの期待の眼差しが向けられていました。

とりわけ、高速化の肝になるであろう `JITコンパイラ`はセッションだけでなくキーノートでも触れられ、大きな注目を集めていました。

しかし、電子計算機の仕組みを独学で（しかも基本情報技術者試験のため）ふわっと勉強した筆者（非情報系卒）にとっては、いささか難しい内容で、オープンされるスライドのたびに変わる会場の空気を「完全に理解した」とは口が避けても言えませんでした。

それでも、`JITコンパイラ`をはじめとする数々の試みが、Rubyエンジニアにとって、とても興味深く、同時に楽しいことであることは十分に伝わってきました
今回はrubykaigi2019の残り香を楽しみつつ、多くのセッションでも取り上げたれたJITコンパイラについて、詳しく見ていきたいと思います。

この記事では、JITの概念をふわっと理解するために、ふわっと理解しようとしている筆者が書いています。
もし、誤りや怪しい部分がございましたら、忌憚ないご意見をいただければ幸いです! (>_<)

# JITコンパイラ is なに？

`JITコンパイラ`は Ruby2.6 からオプションで追加された、Rubyを高速に実行しようとする仕組みです。
JIT(Just-In-Time Compiler)とは、コードがまさに実行されるそのときにコンパイルされる仕組みのことで、RubyだけでなくJavaの実行環境でも取り入れられている仕組みです。

>JITコンパイルという用語は、ソフトウェアを構成するモジュールやクラス、関数などの、ある単位のコードがまさに実行されるその時に、コンパイルされることから「Just In Time」の名前が付けられた
wikipediaより　https://ja.wikipedia.org/wiki/%E5%AE%9F%E8%A1%8C%E6%99%82%E3%82%B3%E3%83%B3%E3%83%91%E3%82%A4%E3%83%A9


RubyのJITは`MJIT`という名前がよく出ていますが、しくみを理解する上ではRubyのJITの実装周りの総称として覚えておいて良さそうです。
参考：https://k0kubun.hatenablog.com/entry/ruby26-jit

## これまでとの処理の違い

### Ruby1.9~Ruby2.5 ,デフォルト設定のRuby2.6での実行
<img width="877" alt="スクリーンショット 2019-05-24 13.21.04.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423146/90d9b78c-dbe1-eb2c-2d8a-2263be657716.png">


Rubyはインタープリタ型言語なので、コンパイルして直接機械語に変換されるわけではありません。どうやって実行されているというと、Rubyのコードは字句・構文解析を経て`YARVバイトコード`というものに変換されます。バイトコードはプログラム言語と機械語との中間にあたるようなコードです。

でも`YARVバイトコード`はあくまでバイトコードであって機械語ではないので、CPUはこの `YARVバイトコード` を直接解釈して実行することはできません。
そこで、CPUに変わって`YARVバイトコード`を解釈し、CPUに命令を発行してくれるのがバーチャルマシン(VM)である`YARV`です。

こうしてRubyのコードは、明示的な機械語へのコンパイルを必要とせずに、実行することができます。

### MJITを有効にしたRuby2.6

（これらの理解の拠り所として [Cコンパイラを利用したRubyのJITコンパイラ](https://speakerdeck.com/k0kubun/programming-symposium-60) を参考にさせていただきました。）

`YARVバイトコード` が生成されるところまではこれまでと変わりません。
そして、バーチャルマシンである`YARV`もこれまで通り登場しますが、`JITコンパイラー`という役者が増えています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/423146/0d501e0a-e1cf-2b8b-1f9f-266a34990fbb.png)


あるプログラムが実行されたとき、`YARV`(以下VM) は生成された `YARVバイトコード`を解釈し、CPUが理解できる命令を発行し、実行してくれます。

ここで、あるメソッドが5回以上呼ばれたとします。そのときVMのスレッドは、JITのキューに、このメソッドを積みます。
JITはVMとは別のスレッドで動いて、積まれたメソッドを`YARVバイトコード`からCのコードに変換します。
生成されたCのコードはやがて`機械語`に変換され`.soファイル`が生成されます。
`.soファイル`の中身はバイナリコード（=機械語)です。これは動的にVMから呼ばれるようにリンクされます。

なので、もし次のタイミングでVMが処理しようとしている`YARVバイトコード`の中に、先ほど`JITコンパイラ`が処理したのと同じメソッドがあった場合、
VMは`YARVバイトコード`を解釈してメソッドを実行するの**ではなく**、機械語にコンパイル済みのメソッド`.soファイル`を関数ポインタを通じて読み込むことで、より高速に同メソッドを実行することができます。

# 現状での速さ/ベンチマーク

JITの仕組みによりRubyの高速化が図られたわけですが、いったいどれだけ早くなったのかというデータは検証方法によってバラツキがあるようです。

これはCコードを生成する際の最適化、Cコードから機械語に翻訳する際の最適化など、様々な要素が絡みあっているからのようで、単純に「何倍早くなった！」と言えるわけではないようでした。

また、JITを有効にして`Ruby on Rails`で作成したWebアプリケーションを実行すると、かえって遅くなるようなデータもrubykaigiでは示されていました。
ただ最新の実験ではJITを有効化しても、無効化時と同程度のスコアが出るようにはなったそうです....ここからが本番。(2019/4 rubykaigi)

（これは筆者の感覚的理解ですが、単純に処理が増えたのだからそれは遅くなっても仕方なさそうだし、プログラムの実行時間が長くなり機械語にコンパイル済みのメソッドが増えれば増えるほど高速化してゆくようなパラダイムでもあるし....納得、という感じです。）


さらに、JIT以外の速度改善についても、「rubyのインタープリタをrubyで書く」といった内容があり、非常に興味のそそるものでした。[RubyKaigi 2019: Write a Ruby interpreter in Ruby for Ruby 3](https://techlife.cookpad.com/entry/2019/04/17/014142)


# おわりに
rubykaigiを振り返ると自分はいかにRubyを知らなかったのか思い知らされます。日常的にRailsに触っていると、Railsが行ってくれている魔術が当たり前になってしまうことがあったかもしれません。
一方、周りを見渡すと、Railsを使いながらもRubyで内製ツールを作って開発効率を上げている例が多くあることを知り、そういった活動が組織の技術力を作り、またOSSの活動へと広がってゆくことを実感しました。

Rubyというプログラミング言語を通し、技術に向き合うとうことを再確認したrubykaigiの３日間でした。

# 参考にた書籍/Webページ

[Rubyのしくみ -Ruby Under a Microscope-](https://www.amazon.co.jp/dp/4274050653)
[Ruby 2.6にJITコンパイラをマージしました|k0kubun's blog](https://k0kubun.hatenablog.com/entry/ruby26-jit)
[プロと読み解く Ruby 2.6 NEWS ファイル|クックパッド開発者ブログ](https://techlife.cookpad.com/entry/2018/12/25/110240)
[Cコンパイラを利用したRubyのJITコンパイラ / Programming Symposium 60](https://speakerdeck.com/k0kubun/programming-symposium-60)

_________________________________________
LITALICOではエンジニアを積極採用中です。
新卒・第二新卒（未経験含）/中途採用、いずれも行なっていますので、ご興味のある方は下記URLをご確認ください。
https://www.wantedly.com/projects/309158