【Ruby 3.0 Advent Calendar 2020】Ruby3.0でRubyで実装されたメソッドたち【3日目】

はじめに

Ruby 3.0 Advent Calendar 2020 3日目の記事になります。

昨日は、【Ruby 3.0 Advent Calendar 2020】Ruby3.0に投げたPull Request【2日目】です。

gamelinks007.hatenablog.com

今日はRuby 2.7から対応されている一部メソッドがRubyで実装されていることに触れつつ、Ruby3.0でRubyで実装されたメソッドたちを一部紹介します。

RubyRubyを実装する

まずRubyRubyを実装するというのがいまいちピンとこない方もいると思いますので軽く説明します。

RubyRubyを実装するという提案はko1さんがRubyKaigi 2019で発表された内容を元に導入されました。

rubykaigi.org

youtu.be

発表されている内容をかいつまむと、組み込みメソッドでキーワード引数を受け取るメソッドやメソッドの内部で例外処理(Cのコードでrb_rescue()を使用しているケース)をしている場合などで高速化できるというものです。
ただし、キーワード引数周りで高速化する場合はキーワード引数を渡さず実行すると遅くなる可能性があります。

また最近ではInteger#to_iのような自分自身を返す組み込みメソッドなども高速化(またはCのコードで実装した場合と同程度の速度)ができることが分かっています。

実はRuby 2.7の段階で既に一部のメソッドはRuby(とC)で書かれていたりします。
具体的にはKernel#warnとかTracePoint#inspectとかですね。

今日はRuby3.0で新しくRuby(とC)で実装されたメソッドを一部ですが紹介していきます。

Rubyで実装されたメソッドたち

Arrayクラス

*** Array#shuffle! & Array#shuffle

github.com


github.com


Array#shuffle!Array#shuffleはキーワード引数としてramdomを指定でき、渡したRamdomオブジェクトを元に疑似乱数列を作ることができます。

キーワード引数を使っている組み込みメソッドなので高速化の一環としてRubyで実装されていると思われますね。

*** Array#sample

github.com


こちらも同様にキーワード引数としてramdomを指定できます。こちらは乱数ジェネレータとして使用されているようです。
同様に高速化の一環としてRubyで実装されていると思われます。

Dirクラス

*** Dir.open & Dir.new

github.com


github.com


引数に渡したpathを元にディレクトリストリームを開く特異メソッドです。
キーワード引数でディレクトリのエンコーディングを指定することができます。

なので、今後は少しディレクトリを開くのが速くなるかもしれませんね。

*** Dir.[] & Dir.glob

github.com

github.com


パターンにマッチするファイル名を文字列の配列として返す特異メソッドです。
basesortなどのキーワード引数でベースディレクトリの指定やソートなどが指定できます。

キーワード引数周りの高速化の一環として導入されているようです。
つまりRuby3.0では今までより少し速くディレクトリの走査ができそうですね!

Integerクラス

Integer#abs & Integer#magnitude


github.com

自分自身の絶対値を返すメソッドです。
このメソッドはキーワード引数などは使われていませんが、高速化出来ているものです。
また特徴的な点は、selfをCの関数に渡している点ですね。

この実装が入る少し前にRuby側の変数をCの関数に渡すことができるようになるコミットが入っています(ただし、組み込みメソッドの実装でのみですね)
これを使って実装されているため速度向上などが図れたと思われます。

Kernelモジュール

Kernel#clone

github.com

オブジェクトの複製を返すメソッドです。キーワード引数を使うことでfreezeされたオブジェクトを返すこともできます。
これもキーワード引数周りの高速化で導入されたものですね。

ちなみにこれは僕がPR出したやつだったりします。

Kernel#Float

github.com

引数に渡されたものをFloatへと変換を試みるメソッドです。
キーワード引数で例外を返すかどうかを選ぶことができます。

これも僕がPR出したもので結構速くなってます。

おわりに

ここで紹介したメソッドたちはRubyで実装されたメソッドの中の一部です。
これ以外にもいくつかのメソッドがRubyで実装されています。

また現在、僕が投げている提案ではTrueClassのいくつかのメソッドをRubyで書いて高速化できるんじゃないかと考えています。

bugs.ruby-lang.org

このようにRubyを書くことでRuby本体の性能向上に一役買うことも今後できるかもしれません
「Cは書けないけど、Rubyなら書ける」という方も今後コントリビューションできるようになるかもしれないので夢が広がりそうですね