👆で Ruby の case 文でクラス名を判定する時に、クラスそのものでもclass.name
でも判定できるので、どちらのほうが処理が速いのか気になりました。
JS脳的なイメィジだとなんとなくStringでの完全一致の方が速そうな気がしたのでど、どうなんでしょう?と先輩に訊いてみた所、benchmark-ips を使ったベンチマークのとり方を教えてくれました。
benchmark-ips
このGemでベンチマークすると「処理回数(イテレーション回数)/秒」を計測してくれます。 次の項で説明するRuby標準のbenchmarkライブラリは自分で実行回数を指定しなければならないのですが、こちらはその手間がなく、かつ処理ごとに何倍の速度差があるかを出してくれるので便利です。
ref. Rubyでベンチマークを取る - Qiita
install
$ gem install benchmark-ips
使い方
公式から引用 GitHub - evanphx/benchmark-ips: Provides iteration per second benchmarking for Ruby
require 'benchmark/ips' Benchmark.ips do |x| # Configure the number of seconds used during # the warmup phase (default 2) and calculation phase (default 5) x.config(:time => 5, :warmup => 2) # These parameters can also be configured this way x.time = 5 x.warmup = 2 # Typical mode, runs the block as many times as it can x.report("addition") { 1 + 2 } # To reduce overhead, the number of iterations is passed in # and the block must run the code the specific number of times. # Used for when the workload is very small and any overhead # introduces incorrectable errors. x.report("addition2") do |times| i = 0 while i < times 1 + 2 i += 1 end end # To reduce overhead even more, grafts the code given into # the loop that performs the iterations internally to reduce # overhead. Typically not needed, use the |times| form instead. x.report("addition3", "1 + 2") # Really long labels should be formatted correctly x.report("addition-test-long-label") { 1 + 2 } # Compare the iterations per second of the various reports! x.compare! end
Benchmark.ips
内で report
に表示するテスト名と測定したい処理を渡して、最後に compare!
を書いておけばどれが一番早かったといったレポートが表示できるようです。
case でクラスを判定する処理速度を測ってみる
クラスそのもので比較した場合と、class.name
で文字列にしたものとで比較してみました。
class_name_case_bentchmark.rb
require 'benchmark/ips' class A def compare_as_class 100000.times do case self when B when A end end end def compare_as_string 100000.times do case self.class.name when "B" when "A" end end end def compare_as_variable_string ckassName = self.class.name 100000.times do case ckassName when "B" when "A" end end end end class B end Benchmark.ips do |x| x.config(:time => 5, :warmup => 2) x.report("self") { A.new.compare_as_class } x.report("self.class.name") { A.new.compare_as_string } x.report("string") { A.new.compare_as_variable_string } x.compare! end
👇 測定
$ ruby class_name_case_bentchmark.rb Warming up -------------------------------------- self 11.000 i/100ms self.class.name 7.000 i/100ms string 13.000 i/100ms Calculating ------------------------------------- self 114.599 (± 2.6%) i/s - 583.000 in 5.091943s self.class.name 74.064 (± 5.4%) i/s - 371.000 in 5.024619s string 130.946 (± 2.3%) i/s - 663.000 in 5.065531s Comparison: string: 130.9 i/s self: 114.6 i/s - 1.14x slower self.class.name: 74.1 i/s - 1.77x slower
Ruby v2.5.5 で100000回試行してみた結果としては、クラス名を変数にしておき文字列で比較した方が若干高速なようでした。
ただ class.name
にアクセスするのに時間がかかるようなので、何千回と連続で判別させるのではないのであれば、クラスそのもので比較するで十分だと思いました。
[参考]
- GitHub - evanphx/benchmark-ips: Provides iteration per second benchmarking for Ruby
- Rubyでベンチマークを取る - Qiita
JX FITNESS 多機能フラットウェイトベンチ シットアップベンチ ダンベル収納ラック付き多用途のトレーニングベンチ.
- 出版社/メーカー: JIANGSU JUNXIA GYM EQUIPMENT CO.,LTD
- メディア: その他
- この商品を含むブログを見る