2019年度Rubyアソシエーション開発助成 に採択された
Rubyアソシエーションが主催する 2019年度Rubyアソシエーション開発助成 に提案プロジェクトが採択されました。
題目は「複数ファイルに対応したプリコンパイル機構の作成」です。
Cookpad株式会社でのインターン に参加した際、メンターの方からの勧めがあり応募したところ審査を通過しました。
以下が応募の際に提出した提案の内容です (一部省略)。
応募者名・担当者名
永山 涼雅
連絡先電子メールアドレス
(省略)
略歴
(省略)
https://bugs.ruby-lang.org/issues/16163
プロジェクト名
複数ファイルに対応したプリコンパイル機構の作成とRubyインタプリタ起動の高速化
プロジェクトの詳細
RubyVMの中間表現である InstructionSequence (ISeq) はバイナリデータの入出力機能を備えている。
- 出力:
RubyVM::InstructionSequence#to_binary
- 入力:
RubyVM::InstructionSequence.load_from_binary
これらを用いてRubyスクリプトのコンパイル結果であるISeqをバイナリデータとしてキャッシュすれば、構文解析やコード生成などの処理を省略できる。実際にRails 5.2以降ではプロジェクトにデフォルトインストールされるgemであるBootsnap (https://github.com/Shopify/bootsnap/) は、 上記の機能を用いてRailsプロジェクトの起動速度の向上に成功している。
しかし、Bootsnapが行っているのはあくまで個別の
.rb
ファイル単位でのキャッシュであり、 gemもしくはプロジェクトといった複数ファイルからなる単位でキャッシュを作成することはできない。 そのため、ファイル間で共通のオブジェクト(例えばシンボルや文字列など)のバイナリ表現の共有などが行えず、 場合によっては内容の重複したオブジェクトが複数生成されることがあった。複数のスクリプトファイルから単一のバイナリを生成できるように現在のISeqの入出力機能を拡張することで、
object_list
(#to_binary
内部で用いられているオブジェクトをシリアライズするための機構) を複数スクリプトファイル間で共有することが可能になるため、 さらなるバイナリサイズの削減や、ロードの高速化が期待できる。また、Rubyインタプリタが起動時にロードする一部のgem (
rubygems
、did_you_mean
など) は Bootsnapの初期化前に読み込まれてしまうため原理的にキャッシュできない。本プロジェクトは、以下の2つの項目の達成を目標とする。
- 複数ファイルからなるgemやプロジェクトを単一のバイナリファイルにプリコンパイルする機構を提供し、Rubyアプリケーションの起動を高速化する。
- インタプリタ起動時に読み込まれるgemをプリコンパイルすることでRubyインタプリタ自体> の起動を高速化する。
プロジェクトの成果物
未着手
また、同じくメンターの方からの勧めで 平成Ruby会議 01 で対外にインターンの成果発表をすることになりました。
以下、提出したCFPです (一部省略)。
発表タイトル
Ruby2.7以降のiseqのバイナリ表現の改善について、Rubyアソシエーション開発助成金2019採択プロジェクトの途中経過について
発表の概要
Ruby2.7に取り込まれたInstructionSequenceのバイナリ表現の改善とその実装について。 上記の概要は以下の記事に公開してしますが、さらに踏み込んでバイナリ表現の形式などについて発表したいと考えています。 https://techlife.cookpad.com/entry/2019/09/26/143000
また、上記を利用・拡張し、複数のRubyファイルを1つのバイナリにプリコンパイルする機構を作成するプロジェクトがRubyアソシエーション開発助成金2019に採択されたので、そのアプローチや実装についての発表。
この発表を聴いた人が何を持ち帰れるか
・iseqバイナリ表現のデータ構造についての理解 ・Ruby2.7のiseqのバイナリ表現にどのような変更があったか、またその影響 ・Rails5.2以降で有効になっているBootsnapが(バイナリ表現を用いて)どのようにRailsアプリケーションの高速化を行っているか ・CRuby本体に手を加えるときのノウハウについて
GitHubアカウント
NagayamaRyoga
Twitterアカウント
(無記入)
ご質問やご要望があればご記入ください
(無記入)