LoginSignup
8
3

More than 5 years have passed since last update.

推測するな計測せよ(activerecord, pluck, map)

Last updated at Posted at 2017-06-26
コードの林を進む中、僕は手元のコンパスを見た。\\
そのコンパスには「こっちが北っぽい」とだけあった。

そんなのだと死にます:chicken:
リファクタする時に速いらしいという推測だけだとあの手この手があるので最良の選択ができません。
プログラマの偉い人が言いました、「推測するな計測せよ:moyai:」。

activerecordとpluckとmapでeachで回す時を例に、
rubyを使って計測してみましょう。

計測 :chart_with_upwards_trend:

def ar_each
  Category.all.each do |c|
    c.name
  end
end

def pluck_each
  Category.all.pluck(:name).each do |name|
    name
  end
end

def map_each
  Category.all.map(&:name).each do |name|
    name
  end
end

Benchmark.bm 10 do |r|
  r.report "activerecord" do
    1000.times { ar_each }
  end
  r.report "pluck" do
    1000.times { pluck_each }
  end
  r.report "map" do
    1000.times { map_each }
  end
end

計測結果 :chart_with_downwards_trend:

=> [#<Benchmark::Tms:0x007fe6a736b8a8
  @cstime=0.0,
  @cutime=0.0,
  @label="activerecord",
  @real=1.6582986700013862,
  @stime=0.20999999999999996,
  @total=1.3299999999999996,
  @utime=1.1199999999999997>,
 #<Benchmark::Tms:0x007fe6a7d0b610
  @cstime=0.0,
  @cutime=0.0,
  @label="pluck",
  @real=0.6788127159961732,
  @stime=0.06000000000000005,
  @total=0.43000000000000016,
  @utime=0.3700000000000001>,
 #<Benchmark::Tms:0x007fe6a70b3570
  @cstime=0.0,
  @cutime=0.0,
  @label="map",
  @real=1.6277251890060143,
  @stime=0.21999999999999997,
  @total=1.3099999999999998,
  @utime=1.0899999999999999>]

この計測結果から、このケースだとpluckが速いことが分かります。

ただケースバイケース

この例だと、pluckが一番速いです。
ただ、1000回繰り返してやっと1秒の差なので、
シンプルに使えるactiverecordのままeach回したほうが楽です。
また、具体例は忘れてしまいましたがpluckよりもmapのほうが速くなる時もあります。
pluck選ぶ!pluckが速いらしいから。と推測するのはやめましょう。
ただプロジェクト全体でpluckに統一しちゃえば全体的に処理が軽くなるかもしれません:hugging:
計測して使うメソッドを決めましょう。:rabbit::turtle:

8
3
7

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
8
3