はじめに
Ruby 3.0 Advent Calendar 2020 3日目の記事になります。
昨日は、【Ruby 3.0 Advent Calendar 2020】Ruby3.0に投げたPull Request【2日目】です。
今日はRuby 2.7から対応されている一部メソッドがRubyで実装されていることに触れつつ、Ruby3.0でRubyで実装されたメソッドたちを一部紹介します。
RubyでRubyを実装する
まずRubyでRubyを実装するというのがいまいちピンとこない方もいると思いますので軽く説明します。
RubyでRubyを実装するという提案はko1さんがRubyKaigi 2019で発表された内容を元に導入されました。
発表されている内容をかいつまむと、組み込みメソッドでキーワード引数を受け取るメソッドやメソッドの内部で例外処理(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
Array#shuffle!
と Array#shuffle
はキーワード引数としてramdom
を指定でき、渡したRamdom
オブジェクトを元に疑似乱数列を作ることができます。
キーワード引数を使っている組み込みメソッドなので高速化の一環としてRubyで実装されていると思われますね。
*** Array#sample
こちらも同様にキーワード引数としてramdom
を指定できます。こちらは乱数ジェネレータとして使用されているようです。
同様に高速化の一環としてRubyで実装されていると思われます。
Dirクラス
*** Dir.open & Dir.new
引数に渡したpathを元にディレクトリストリームを開く特異メソッドです。
キーワード引数でディレクトリのエンコーディングを指定することができます。
なので、今後は少しディレクトリを開くのが速くなるかもしれませんね。
*** Dir.[] & Dir.glob
パターンにマッチするファイル名を文字列の配列として返す特異メソッドです。
base
やsort
などのキーワード引数でベースディレクトリの指定やソートなどが指定できます。
キーワード引数周りの高速化の一環として導入されているようです。
つまりRuby3.0では今までより少し速くディレクトリの走査ができそうですね!
Integerクラス
Integer#abs & Integer#magnitude
自分自身の絶対値を返すメソッドです。
このメソッドはキーワード引数などは使われていませんが、高速化出来ているものです。
また特徴的な点は、self
をCの関数に渡している点ですね。
この実装が入る少し前にRuby側の変数をCの関数に渡すことができるようになるコミットが入っています(ただし、組み込みメソッドの実装でのみですね)
これを使って実装されているため速度向上などが図れたと思われます。
Kernelモジュール
Kernel#clone
オブジェクトの複製を返すメソッドです。キーワード引数を使うことでfreeze
されたオブジェクトを返すこともできます。
これもキーワード引数周りの高速化で導入されたものですね。
ちなみにこれは僕がPR出したやつだったりします。
Kernel#Float
引数に渡されたものをFloat
へと変換を試みるメソッドです。
キーワード引数で例外を返すかどうかを選ぶことができます。
これも僕がPR出したもので結構速くなってます。