Ruby 2.7が公開、関数型言語で広く使われているパターンマッチ機能などを追加:メモリ利用効率向上や高速化も実現
Ruby開発チームは、オープンソースのプログラミング言語「Ruby」の最新安定版「Ruby 2.7.0」をリリースした。パターンマッチ機能の導入やREPLの改善、ヒープコンパクションの追加など多数の改良を施した。
Ruby開発チームは2019年12月25日、オープンソースのオブジェクト指向スクリプト言語「Ruby」の最新安定版「Ruby 2.7.0」をリリースしたと発表した。
Ruby 2.7.0では多くの新機能を追加し、パフォーマンスを改善した。主な改良点は次の通り。
パターンマッチ機能を導入
関数型言語で広く使われているパターンマッチ機能を実験的に導入した。これにより、渡されたオブジェクトの構造がパターンと一致するかどうかを調べ、一致した場合にその値を変数に代入するといったコードを記述しやすくなった。
require "json" json = <<END { "name": "Alice", "age": 30, "children": [{ "name": "Bob", "age": 2 }] } END case JSON.parse(json, symbolize_names: true) in {name: "Alice", children: [{name: "Bob", age: age}]} p age #=> 2 end
REPLを改善
Rubyに添付されている「REPL(Read-Eval-Print-Loop)」である「irb」において、複数行編集をサポートした。さらにドキュメント生成コマンド「rdoc」との連携も実現した。これにより、irb内でクラスやモジュール、メソッドのレファレンスをその場で確認できるようになった。
GC.compactメソッドの導入
断片化したメモリをデフラグする「Compaction GC」を導入した。具体的には「GC.compact」メソッドを追加した。このメソッドを実行するたびに、ヒープのコンパクションを実行する。
Rubyのオブジェクトはヒープに格納されており、オブジェクトを格納するスロットの並びであるページの集合としてヒープを実装している。Rubyにおけるヒープのコンパクションは、空きスロットのあるページに対して、生きているオブジェクトを別のページから動かして詰めていくことで、メモリの断片化を解消し、不要なページを解放する。
通常の引数とキーワード引数を分離
キーワード引数と「positional」な引数(普通の引数)の自動変換を非推奨とした。この変換機能は、次期主要アップデートであるRuby 3で削除する予定。
Ruby 2では、キーワード引数を単なるハッシュとして渡すという基本設計を採用していたが、このような設計は数多くの非直感的挙動を引き起こしている。そこでRuby 3では、この問題を解決するため、キーワード引数と普通の引数を分離することにした。
機能を削除する先駆けとして、Ruby 3では動かなくなる非推奨の機能を用いたコードに警告を出すようにした。
番号指定パラメーターなどを追加
- デフォルトのブロックの仮引数として番号指定パラメーターを導入した
- 開始値省略範囲式を試験的に導入した
ary[..3] # identical to ary[0..3] rel.where(sales: ..100)
- 各要素の出現回数を数える「Enumerable#tally」を追加した
["a", "b", "c", "b"].tally #=> {"a"=>1, "b"=>2, "c"=>1}
- レシーバーをselfとしたprivateメソッドの呼び出しを許容した
def foo end private :foo self.foo
- 「Enumerator::Lazy」から「Enumerator」に変換するメソッドである「Enumerator::Lazy#eager」を追加した
a = %w(foo bar baz) e = a.lazy.map {|x| x.upcase }.map {|x| x + "!" }.eager p e.class #=> Enumerator p e.map {|x| x + "?" } #=>
パフォーマンスを改善
パフォーマンスを改善するために、JIT(Just-In-Time)コンパイラの実験的改善などを施した。
最適化の際に仮定していた条件が無効になった場合、JIT化されていたコードを、より最適化度が低いコードに再コンパイルするようにした。
同様にJIT関連では、「--jit-min-calls」オプションのデフォルト値を5から10000に変更し、「--jit-max-cache」オプションのデフォルト値を1000から100に変更した
また、あるメソッドが「純粋」であると判定された場合、メソッドのインライン化を行うようにした。この最適化はまだ実験的な位置付けにある。さらに、多数のメソッドが現時点では「純粋」と判定されていない。
この他、パフォーマンス改善につながる変更点は次の通り。
- Fiberのキャッシュ戦略を変更することで、生成を高速化した
- 「Module#name」や「true.to_s」「false.to_s」「nil.to_s」が、常に「frozen」な文字列を返すようになった。返された文字列は常に同じオブジェクトになる
- 「CGI.escapeHTML」のパフォーマンスを改善した
- 「Monitor」と「MonitorMixin」のパフォーマンスを改善した
- Ruby 1.9から導入したメソッド呼び出しごとのキャッシュを改良し、キャッシュヒット率が89%から94%に向上した
- 「RubyVM::InstructionSequence#to_binary」が生成するコンパイル済みバイナリのサイズが小さくなるように改善した
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
Ruby 2.6が公開、JITコンパイラを実装
「Ruby 2.6.0」が公開された。JIT(Just-In-Time)コンパイラが導入されたことに加え、処理性能を向上させる改善が複数施されている。終点なしRangeなどの新機能も実装された。Rubyの面白さを理解するためのメソッド、ブロック、Proc、lambda、クロージャの基本
オープンソースのオブジェクト指向プログラミング言語「Ruby」の文法を一から学ぶための入門連載。最新版の2.1に対応しています。今回は、Rubyのメタプログラミングを学ぶ上での基礎知識となるメソッド、ブロック、Proc、lambda(ラムダ)、クロージャなどの基本的な使い方について。GCの変更と高速化を盛り込んだRuby 2.1.0
2013年末、クリスマスの日に予告通りRubyの新バージョンがリリースされた。GCの変更やライブラリのアップデートも行われている。