Posted by naruse on 25 Dec 2021
Ruby 3.1系初のリリースである、Ruby 3.1.0 が公開されました。Ruby 3.1は3.0と高い互換性を保ちながら、多くの機能を追加しています。
YJIT: New experimental in-process JIT compiler
Ruby 3.1では、Shopifyが開発した新しいプロセス内JITコンパイラであるYJITをマージしました。
2018年のRuby 2.6でMJITをマージして以来、そのパフォーマンスは年々改善され、去年にはRuby3x3を無事達成しました。比較的大規模なOptcarrotベンチマークでは輝かしい高速化を達成したMJITですが、一方で現実の業務アプリケーションの性能はこれまで改善出来ていませんでした。
近年Shopifyは彼らのRailsアプリケーションを高速化するため、Rubyに対して多くの貢献をしてきました。YJITはその中でも重要な貢献であり、Railsアプリケーションをさらに高速化するために開発されました。
MJITがメソッドベースのJITコンパイラであり、外部のCコンパイラを利用しているのに対し、YJITではBasic Block Versioningという技術を用いた独自のJITコンパイラをRuby内部に持っています。YJITの用いているLazy Basic Block Versioning (LBBC)では、まずメソッドの冒頭のみをコンパイルし、実行時に実際に値が渡されて引数や変数の値が明らかになってから残りをコンパイルするという手法を用いることで、動的プログラミング言語においても効率のよいJITを実現しています。詳細は YJIT: a basic block versioning JIT compiler for CRuby を参照ください。
これらの技術によって、YJITでは素早い起動と高速な実行を多くの実世界のアプリケーションに対して実現しており、railsbenchでは最大22%、liquied-renderでは39%の高速化を達成しています。
YJITはまだ実験的機能なため、デフォルトでは無効化されています。試してみたい場合には --yjit
コマンドラインオプションを指定することでYJITを有効化出来ます。現在YJITはx86-64上のUnix系プラットフォームでのみ実行出来ます。
- https://bugs.ruby-lang.org/issues/18229
- https://shopify.engineering/yjit-just-in-time-compiler-cruby
- https://www.youtube.com/watch?v=PBVLf3yfMs8
debug gem: 新しいデバッガ
完全に0から書き直したデバッガである debug.gem が同梱されました。次のような特徴があります。
- デバッグ時の速度低下を極力生じないよう改善
- リモートデバッグのサポート
- リッチなデバッガフロントエンドに対応(現在 VSCode と Chrome ブラウザに対応)
- マルチプロセス、マルチスレッドプログラムのデバッグに対応
- カラフルな REPL
- そのほか、Record & Replay 機能やトレース機能など、様々な便利機能
Rubyにはこれまでも lib/debug.rb が同梱されていましたが、あまりメンテナンスされておらず、性能や機能に問題がありました。debug.gem はこれを完全に置き換えます。
error_highlight: バックトレース中の詳細なエラー位置表示
error_highlightという組み込みgemが導入されました。これにより、バックトレース中でエラーが発生した詳細な位置が表示されます。
$ ruby test.rb
test.rb:1:in `<main>': undefined method `time' for 1:Integer (NoMethodError)
1.time {}
^^^^^
Did you mean? times
現在のところ、位置が表示されるのはNameError
のみです。
このgemはデフォルトで有効になっています。--disable-error_highlight
コマンドラインオプションを指定することで無効化できます。詳しくはruby/error_highlightリポジトリを見てください。
IRB のオートコンプリートとドキュメント表示
IRB にオートコンプリート機能が実装され、コードを入力するだけで補完候補ダイアログが表示されるようになりました。Tab と Shift+Tab で上下に移動できます。
また、補完候補を選択している時に、ドキュメントがインストールされている場合、補完候補ダイアログの横にドキュメントダイアログが表示され、内容が一部表示されます。Alt+d を押すことでドキュメント全文を読むことができます。
その他の主要な新機能
言語機能
- ハッシュリテラルやキーワード引数の値が省略可能になりました。 [Feature #14579]
{x:, y:}
は、{x: x, y: y}
の糖衣構文です。foo(x:, y:)
は、foo(x: x, y: y)
の糖衣構文です。
-
パターンマッチ中のピン演算子に任意の式を書けるようになりました。 [Feature #17411]
Prime.each_cons(2).lazy.find_all{_1 in [n, ^(n + 2)]}.take(3).to_a #=> [[3, 5], [5, 7], [11, 13]]
-
一行パターンマッチで括弧が省略できるようになりました. [Feature #16182]
[0, 1] => _, x {y: 2} => y: x #=> 1 y #=> 2
RBS
RBSはRubyプログラムの型を定義するための言語です。
3.0.0からは、次の様なアップデートがありました。
- ジェネリクスの型パラメータに制約を与えることができるようになりました。 (PR)
- ジェネリックな型エイリアスが定義できようになりました。 (PR)
- gemのRBSを管理するための
rbs collection
コマンドが導入されました。 (doc) - いろいろな組み込みクラスの型定義が追加、更新されました。
- 多数のバグ修正と性能の改善が含まれています。
詳しくはCHANGELOG.mdを確認してください。
TypeProf
TypeProfはRubyの静的型解析器です。型注釈のないRubyコードから、RBSのプロトタイプを生成します。詳しくはドキュメントをご参照ください.
Ruby 3.0.0からの主なアップデートは、”TypeProf for IDE”という実験的なIDEサポートです。
このVSCode拡張は、推定された(またはRBSファイルに手で明記された)メソッドのシグネチャを、各メソッド定義の上に表示します。 また、NameErrorやTypeErrorを起こしうるコードを赤い下線で示します。 さらに、メソッド名の補完(メソッド名の候補の表示)を行います。 詳しくはドキュメントをご参照ください。
また、数多くのバグ修正やパフォーマンス向上がなされています。
パフォーマンスの改善
- MJIT
- For workloads like Rails, the default
--jit-max-cache
is changed from 100 to 10000. The JIT compiler no longer skips compilation of methods longer than 1000 instructions. - To support Zeitwerk of Rails, JIT-ed code is no longer cancelled when a TracePoint for class events is enabled.
- For workloads like Rails, the default
その他の注目すべき 3.0 からの変更点
-
一行パターンマッチ(たとえば
ary => [x, y, z]
)が実験的機能ではなくなりました。 - 多重代入の評価順序が若干変更されました。[Bug #4443]
foo[0], bar[0] = baz, qux
は、Ruby 3.0 ではbaz
,qux
,foo
,bar
という順序で評価されていましたが、Ruby 3.1 ではfoo
,bar
,baz
,qux
の順で評価されます。
-
可変幅アロケーション(Variable Width Allocation)が実装されました。現在は試験的にStringが対応しています。 [Bug #18239]
- Psych 4.0 では
Psych.load
がsafe_load
を利用するように変更されました。この挙動が影響ある場合は、従来の挙動であるunsafe_load
を利用する Psych 3.3.2 を移行パスとして利用できます。[Bug #17866]
標準添付ライブラリのアップデート
- 以下の default gems のバージョンがアップデートされました。
- RubyGems 3.3.3
- base64 0.1.1
- benchmark 0.2.0
- bigdecimal 3.1.1
- bundler 2.3.3
- cgi 0.3.1
- csv 3.2.2
- date 3.2.2
- did_you_mean 1.6.1
- digest 3.1.0
- drb 2.1.0
- erb 2.2.3
- error_highlight 0.3.0
- etc 1.3.0
- fcntl 1.0.1
- fiddle 1.1.0
- fileutils 1.6.0
- find 0.1.1
- io-console 0.5.10
- io-wait 0.2.1
- ipaddr 1.2.3
- irb 1.4.1
- json 2.6.1
- logger 1.5.0
- net-http 0.2.0
- net-protocol 0.1.2
- nkf 0.1.1
- open-uri 0.2.0
- openssl 3.0.0
- optparse 0.2.0
- ostruct 0.5.2
- pathname 0.2.0
- pp 0.3.0
- prettyprint 0.1.1
- psych 4.0.3
- racc 1.6.0
- rdoc 6.4.0
- readline 0.0.3
- readline-ext 0.1.4
- reline 0.3.0
- resolv 0.2.1
- rinda 0.1.1
- ruby2_keywords 0.0.5
- securerandom 0.1.1
- set 1.0.2
- stringio 3.0.1
- strscan 3.0.1
- tempfile 0.1.2
- time 0.2.0
- timeout 0.2.0
- tmpdir 0.1.2
- un 0.2.0
- uri 0.11.0
- yaml 0.2.0
- zlib 2.1.1
- 以下の bundled gems のバージョンがアップデートされました。
- minitest 5.15.0
- power_assert 2.0.1
- rake 13.0.6
- test-unit 3.5.3
- rexml 3.2.5
- rbs 2.0.0
- typeprof 0.21.1
- 以下のライブラリが新たに bundled gems になりました。Bundler から利用する場合は Gemfile に明示的に指定してください。
- net-ftp 0.1.3
- net-imap 0.2.2
- net-pop 0.1.1
- net-smtp 0.3.1
- matrix 0.4.2
- prime 0.1.2
- debug 1.4.0
その他詳細については、NEWS ファイルまたはコミットログを参照してください。
なお、こうした変更により、Ruby 3.0.0 以降では 3124 個のファイルに変更が加えられ、551760 行の追加と 99167 行の削除が行われました !
メリークリスマス、様々な機能が追加された Ruby 3.1 をぜひお楽しみ下さい!
ダウンロード
-
https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.tar.gz
SIZE: 20103517 SHA1: e4e8c20dd2a1fdef4d3e5bd5a3461000dd17f226 SHA256: 50a0504c6edcb4d61ce6b8cfdbddaa95707195fab0ecd7b5e92654b2a9412854 SHA512: 76009d325e961e601d9a287e36490cbc1f3b5dbf4878fa6eab2c4daa5ff2fed78cbc7525cd87b09828f97cbe2beb30f528928bcc5647af745d03dffe7c5baaa9
-
https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.tar.xz
SIZE: 14709096 SHA1: 92b603c2a69fb25d66c337a63e94280984edea11 SHA256: 1a0e0b69b9b062b6299ff1f6c6d77b66aff3995f63d1d8b8771e7a113ec472e2 SHA512: a2bb6b5e62d5fa06dd9c30cf84ddcb2c27cb87fbaaffd2309a44391a6b110e1dde6b7b0d8c659b56387ee3c9b4264003f3532d5a374123a7c187ebba9293f320
-
https://cache.ruby-lang.org/pub/ruby/3.1/ruby-3.1.0.zip
SIZE: 24388179 SHA1: e37435956d6f840a0e8758d7374bc7e0e346105f SHA256: a3bfcd486d09c065d46421da0ff3d430ce4423fefd80cea63c6595d83ae4af0e SHA512: 67db71144e06da2c1c25eaf413d1417c99a4b18738a573f9e3371c11ea242eee9dcbdc3de17336f25ab5060039fe034e57298943d344be9cd9eb33bb56e2e1c6
Ruby とは
Rubyはまつもとゆきひろ (Matz) によって1993年に開発が始められ、今もオープンソースソフトウェアとして開発が続けられています。Rubyは様々なプラットフォームで動き、世界中で、特にWebアプリケーション開発のために使われています。