Fynmdhrz

最近のRuby20160714 - want-valueというアイディアCreated on 2016-07-14 by naruse

突然の新連載です、わぁい。

この連載は、はてなの日記に書くほどまとまっていないけれど、Twitterに書くほど短くもない微妙な粒度のネタを世間に放流するための連載です。不定期にネタのあるときに書かれる予定です。

さて、CRuby界隈ではRuby 3x3という夢のぶち上げ以来高速化が一段と盛り上がっているわけですが、その具体的な方針についてもいくつかの案が出ています。

その一つが不要なオブジェクト生成の除去です。Rubyにおいてオブジェクトの生成はそれ単体でも重い処理である上に、オブジェクトの廃棄(=GC)の際にもコストがかかります。ゆえにこれを削減できればこれには大きく分けて以下の3種類があります。

  • 複数オブジェクトに対する処理に際して作られる一時Array。
  • 不要なメソッド引数
  • 使われない戻り値

1つ目はArray#maxが典型的な例ですね。Array#packみたいな例もあるでしょう。

2つ目は String#gsubを削除に使う場合の空文字列が典型的でしょう。設定として渡され、ゆくゆくはmergeされる空ハッシュとかもありがちでしょうか。

3つ目はString#slice!などの文字通りの使わない戻り値に加えて、多値の戻り値における一時Arrayという例もあります。

これら以外にメソッドチェーンした場合の中間オブジェクトなどもありますが、まぁそんな感じの問題意識です。。

さて、一つ目はどのメソッドを呼ぶかに影響するとはいえ、これは2つ目とあわせて不要な引数として一般化することが出来ます。一方で3つ目は実行されるメソッドそのものに戻り値の生成を抑止するための情報を伝えなければいけません。つまり、PerlのwantarrayのようなVMとメソッドのやりとりをするための仕組みが必要です。

それがwant-valueです。これはYARV命令のコンパイル時にsendの直後にpopが来るケースを検出し、rb_call_info構造体にフラグを渡します。実行時にこのフラグをコールフレームにコピーしておけば、rb_vm_want_value_p()を呼び出すことでC関数は意味のある戻り値の生成が必要かを知ることが出来ます。

実際にRubyにマージするにはもうちょっと議論が必要な拡張ですが、楽しみなネタですね。

追記