5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【初心者必読】Ruby の誤解あるあるAdvent Calendar 2020

Day 24

Ruby のエイリアスメソッドはどれを使っても同じ?

Last updated at Posted at 2020-12-23

Ruby はメソッド名にエイリアス(別名)が多い言語です。
例えば Enumerablemapcollect の二つはエイリアスの関係にあり,どちらを使っても同じ結果になります。
そこで,どちらを使うかは好みの問題となり,「map 派」「collect 派」という言葉まで生まれてしまいました。

では,メソッドに複数の名前があったとき,本当にどれを使っても同じなのでしょうか。
そうとも言い切れない例があります。

Integer には,「レシーバーに 1 足した数を返す」メソッドがあり,nextsucc という二つの名前を持っています。
エイリアスなので機能はもちろん変わらないのですが,速度が違います。

benchmark_driver というベンチマークテスト用 gem をインストールし,

next-succ.yaml
benchmark:
  - 1.next
  - 1.succ

という YAML ファイルを用意して,

benchmark-driver next-succ.yaml

としてみましょう。結果は

       1.succ: 134563685.5 i/s 
       1.next:   8751120.9 i/s - 15.38x  slower

のように,なんと 15 倍もの速度差が出ました。(追記参照のこと)
実験環境:
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin17]

どうしてこんなことになるかというと,RubyVM 上で succ にだけ何らかの最適化が入っているのだそうです。

では,絶対に next でなく succ を使うべきなのでしょうか。
それは場合によるでしょう。
上の結果を見ると,Integer#next だって毎秒 800 万回以上も実行できるのです。
多数回回るループの中で使うとしても,実用的なコードでは,ループの中の他の処理に比べて遙かに軽いことがほとんどでしょう。
マイクロベンチマークでなく現実のコードで succnext の違いが処理速度を左右することはそう多くはないかもしれません。

追記 2021-11-21

いま改めて同じ方法(マシンは違う)でベンチマークをとってみると,15 倍もの差はなく,2 倍程度でした。Ruby 2.6.3,2.7.4,3.0.2 ともそんな感じです。

5
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?