Posted by naruse on 12 Nov 2023
Ruby 3.3.0-preview3 が公開されました。Ruby 3.3ではPrismという新しいパーサーの追加、新しいパーサージェネレーターであるLramaによるBisonの置き換え、RJITという新たなJITの仕組みを追加、YJITの高速化など様々な改善が行われています。
Prism
- Introduced the Prism parser as a default gem
- Prism is a portable, error tolerant, and maintainable recursive descent parser for the Ruby language
- Prism is production ready and actively maintained, you can use it in place of Ripper
- There is extensive documentation on how to use Prism
- Prism is both a C library that will be used internally by CRuby and a Ruby gem that can be used by any tooling which needs to parse Ruby code
- Notable methods in the Prism API are:
Prism.parse(source)
which returns the AST as part of a ParseResultPrism.dump(source)
which returns the serialized AST as a StringPrism.parse_comments(source)
which returns the comments
- You can make pull requests or issues directly on the Prism repository if you are interested in contributing
Use Lrama instead of Bison
- Replace Bison with Lrama LALR parser generator [Feature #19637]
- If you have interest, please see The future vision of Ruby Parser
- See also: Ruby Parser開発日誌 (5) - Lrama LALR (1) parser generatorを実装した
- Lrama internal parser is replaced with LR parser generated by Racc for maintainability
- Parameterizing Rules
(?, *, +)
are supported, it will be used in Ruby parse.y
RJIT
- Introduced a pure-Ruby JIT compiler RJIT and replaced MJIT.
- RJIT supports only x86_64 architecture on Unix platforms.
- Unlike MJIT, it doesn’t require a C compiler at runtime.
- RJIT exists only for experimental purposes.
- You should keep using YJIT in production.
- If you are interested in developing JIT for Ruby, please check out k0kubun’s presentation on Day 3 of RubyKaigi.
YJIT
- Major performance improvements over 3.2
- Support for splat and rest arguments has been improved.
- Registers are allocated for stack operations of the virtual machine.
- More calls with optional arguments are compiled.
- Exception handlers are also compiled.
- Instance variables no longer exit to the interpreter with megamorphic object shapes.
- Unsupported call types no longer exit to the interpreter.
Integer#!=
,String#!=
,Kernel#block_given?
,Kernel#is_a?
,Kernel#instance_of?
,Module#===
are specially optimized.- Now more than 3x faster than the interpreter on optcarrot!
- Significantly improved memory usage over 3.2
- Metadata for compiled code uses a lot less memory.
- Generate more compact code on ARM64
- Compilation speed is now slightly faster than 3.2.
- Add
RubyVM::YJIT.enable
that can enable YJIT later- You can start YJIT without modifying command-line arguments or environment variables.
- This can also be used to enable YJIT only once your application is
done booting.
--yjit-disable
can be used if you want to use other YJIT options while disabling YJIT at boot.
- Option to disable code GC and treat
--yjit-exec-mem-size
as a hard limit- Can produce better copy-on-write behavior on servers using unicorn and forking
ratio_in_yjit
stat produced by--yjit-stats
is now available in release builds, a special stats or dev build is no longer required to access most stats.- Exit tracing option now supports sampling
--trace-exits-sample-rate=N
--yjit-perf
is added to facilitate profiling with Linux perf.- More thorough testing and multiple bug fixes
M:N スレッドスケジューラ
- M:N スレッドスケジューラが導入されました。[Feature #19842]
- M個のRuby スレッドを、N個のネイティブスレッド(OSスレッド)で管理するので、生成管理のコストを抑えることができるようになりました。
- C拡張ライブラリの互換性に問題が生じる可能性があるため、メインRactorでのM:Nスレッドスケジューラはデフォルトでは無効にされています。
RUBY_MN_THREADS=1
と環境変数を設定することで、メインRactorでM:Nスレッドスケジューラを有効にします。- メインRactor以外ではM:Nスレッドスケジューラが有効です。
RUBY_MAX_CPU=n
と環境変数を設定することで、Nの最大数(利用するネイティブスレッドの最大数)を設定できます。デフォルトは8です。- 一つの Ractor ではたかだか1つのスレッドしか同時に実行されないので、実際に利用するネイティブスレッド数は、
RUBY_MAX_CPU
で指定した数か実行中のRactorの数の少ないほうになります。つまり、Ractorの数が1つのアプリケーション(多くのアプリケーション)では1つのネイティブスレッドだけ利用されます。 - ブロックする処理をサポートするため、N個以上のネイティブスレッドが利用されることがあります。
- 一つの Ractor ではたかだか1つのスレッドしか同時に実行されないので、実際に利用するネイティブスレッド数は、
その他の主要な新機能
言語機能
パフォーマンスの改善
Socket.getaddrinfo
などの名前解決を中断できるようになりました (pthread が利用できる環境で)。Feature 19965- このために、getaddrinfo や getnameinfo を呼び出すたびに pthread が生成されるようになりました。名前解決に若干のオーバーヘッドが発生します(実験では約2.5倍)。ほとんどのアプリケーションで名前解決のオーバーヘッドが問題になるとは考えていませんが、もしそのような現象が見られたり、この変更が原因と思われる予期せぬ影響が見られた場合は、ぜひ報告してください。
- 環境変数
RUBY_GC_HEAP_REMEMBERED_WB_UNPROTECTED_OBJECTS_LIMIT_RATIO
が追加されました。Feature #19571 - GCで古いオブジェクトの子オブジェクトがすぐにプロモートされなくなりました。Feature #19678
- GCに弱参照が追加されました。Feature #19783
その他の注目すべき 3.2 からの変更点
IRB
IRBは様々な機能強化を行いました。主なものは以下の通りです。
- IRBとrdbgの連携 pry-byebugのような使い心地でデバッグできるようになりました。(使い方)
- lsコマンドやshow_cmdsの出力がPagerで表示されるようになりました。
- lsコマンドやshow_sourceコマンドがより便利で詳細な情報を出力するようになりました。
- 型情報を使った補完が実験的に実装されました。(有効化するには)
- Reline::Faceクラスの導入により、補完ダイアログの色や文字装飾を変更できるようになりました。(使い方)
また、機能強化以外にも、数多くのバグ修正および将来的な機能拡張を見越した大規模なリファクタリングを行ないました。
互換性に関する変更
定数の削除
以下の非推奨定数は削除されました
メソッドの削除
以下の非推奨のメソッドは削除されました
環境変数の削除
以下の非推奨の環境変数は削除されました
- 環境変数
RUBY_GC_HEAP_INIT_SLOTS
は非推奨になり、何もしなくなりました。環境変数RUBY_GC_HEAP_{0,1,2,3,4}_INIT_SLOTS
を使ってください。Feature #19785
標準添付ライブラリの互換性に関する変更
ext/readline
の削除
- 今後は Ruby で書かれた GNU Readline の互換ライブラリである
reline
をすべての環境で標準で利用し、ext/readline
は削除されました。以前のext/readline
が必要なユーザーはgem install readline-ext
でインストールすることができます。 - この変更により、Ruby のインストール時に
libreadline
やlibedit
などのライブラリのインストールは不要となります。
C API の変更
C API の更新
以下の API が更新されました
C API の削除
以下の非推奨の API は削除されました
標準添付ライブラリのアップデート
RubyGems と Bundler は将来リリースされる Ruby で bundled gems となる予定の gem が require された際に警告を行う機能が追加されました。
以下のライブラリが対象となります。
- abbrev
- base64
- bigdecimal
- csv
- drb
- getoptlong
- mutex_m
- nkf
- observer
- racc
- resolv-replace
- rinda
- syslog
以下の default gem が追加されました。
- prism 0.15.1
以下の default gems のバージョンがアップデートされました。
- RubyGems 3.5.0.dev
- base64 0.2.0
- benchmark 0.3.0
- bigdecimal 3.1.5
- bundler 2.5.0.dev
- cgi 0.4.0
- csv 3.2.8
- date 3.3.4
- delegate 0.3.1
- drb 2.2.0
- english 0.8.0
- erb 4.0.3
- etc 1.4.3.dev.1
- fcntl 1.1.0
- fiddle 1.1.2
- fileutils 1.7.2
- find 0.2.0
- getoptlong 0.2.1
- io-console 0.6.1.dev
- irb 1.8.3
- logger 1.6.0
- mutex_m 0.2.0
- net-http 0.4.0
- net-protocol 0.2.2
- nkf 0.1.3
- observer 0.1.2
- open-uri 0.4.0
- open3 0.2.0
- openssl 3.2.0
- optparse 0.4.0
- ostruct 0.6.0
- pathname 0.3.0
- pp 0.5.0
- prettyprint 0.2.0
- pstore 0.1.3
- psych 5.1.1.1
- rdoc 6.6.0
- reline 0.3.9
- rinda 0.2.0
- securerandom 0.3.0
- shellwords 0.2.0
- singleton 0.2.0
- stringio 3.0.9
- strscan 3.0.7
- syntax_suggest 1.1.0
- tempfile 0.2.0
- time 0.3.0
- timeout 0.4.1
- tmpdir 0.2.0
- tsort 0.2.0
- un 0.3.0
- uri 0.13.0
- weakref 0.1.3
- win32ole 1.8.10
- yaml 0.3.0
- zlib 3.1.0
新たに以下の gem が default gems から bundled gems に変更されました。
- racc 1.7.3
以下の bundled gems のバージョンがアップデートされました。
- minitest 5.20.0
- rake 13.1.0
- test-unit 3.6.1
- rexml 3.2.6
- rss 0.3.0
- net-imap 0.4.4
- net-smtp 0.4.0
- rbs 3.2.2
- typeprof 0.21.8
- debug 1.8.0
default gems と bundled gems の詳細については Logger の GitHub Releases のような GitHub releases または changelog ファイルを参照してください。
その他詳細については、NEWS ファイルまたはコミットログを参照してください。
なお、こうした変更により、Ruby 3.2.0 以降では 5207 個のファイルに変更が加えられ、284820 行の追加と 174773 行の削除が行われました !
ダウンロード
-
https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.0-preview3.tar.gz
SIZE: 21550473 SHA1: 2811f191d66dffee0206771873bd990857ae4ed6 SHA256: 0969141be92e67e0edb84a8fb354acc98f01bd78e602a23a0f136045c82f4809 SHA512: 94db07a6958c09809b2e5b597fa55a121074e8bacb3bf588c83cf0d35b07a8b070172035a49d1abf0d8ee364a9ace824f34e677f7327ffe1acdbab0938ac49c4
-
https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.0-preview3.tar.xz
SIZE: 15970144 SHA1: 496600612605f8ebeb955255e98bac73a4cbc045 SHA256: f79afcf122dc7d04fe26cfa4436b9c488b21766fc54b0d2dfb2ba41cd0cdd355 SHA512: d7ab0d703e7884efd31045933409cd68fac1d9941963537ccc8e309ca7c8bee8500a68182135acba22cbdbf4a8ae99f39bf7f0925273eb4fbc3728c0c1ba0c19
-
https://cache.ruby-lang.org/pub/ruby/3.3/ruby-3.3.0-preview3.zip
SIZE: 26618303 SHA1: 6a13e08c7e484d42037c1e2c87c5d0e220f893a0 SHA256: c35bf637a647c2f60148368ffb374db5c258570911794f46b6dfdb98ebfe95d9 SHA512: c4ef2cdcdadeb85ad1d42aedc97f9f3d609b3b01eea2319451cf92c81bd31ae8129b7c91fc68571469dd888c01ea0f48f73234b965db17f6a87404ca382f7794
Ruby とは
Rubyはまつもとゆきひろ (Matz) によって1993年に開発が始められ、今もオープンソースソフトウェアとして開発が続けられています。Rubyは様々なプラットフォームで動き、世界中で、特にWebアプリケーション開発のために使われています。