LoginSignup
3
3

More than 5 years have passed since last update.

delete_if がやけに遅いけど、compact! と keep_if は普通。

Posted at

先程「ary-[nil]ary.compact」という記事( http://qiita.com/Nabetani/items/ba6b8eea61e03ce48df7 )を書いたんだけど、そういえば delete_if とかもあったよな、と思い、調べてみたら意外な展開に。

まずはグラフ。縦軸は時間。対数目盛注意。

CRuby は、2.1.3。
JRuby は、1.17.15。

dekeco.png

compact がぐねぐねしているのは、誤差。

まず。
配列のサイズと繰り返す数の積が一定になるようにしているんで、計算量が変わらないことを期待しているんだけど、delete_if はどんどん遅くなっている。
対数目盛なのでわかりにくいかもしれないけど、10倍以上遅くなっている。

keep_ifcompact! は期待通り。なんだろうこれ。

delete_if の後半以外は CRuby が速いけど、delete_if の後半だけは JRuby が速いというところも面白い。

delete_if には副作用のないバージョンがないので、公平を期すために、compact の代わりに dup.compact! にしている。

測定に使ったソースコードは以下のとおり:

require "benchmark"

puts "array size,trial count,label,delete_if,keep_if,compact"
2.to_r.step(7,1.to_r/6) do |ary_size_e|
  ary_size =(10**ary_size_e).ceil.to_i
  src=Array.new(ary_size){  |n|
    n%2==0 ? nil : n
  }

  trial = (10**7/ary_size ).ceil
  print "array size : #{ary_size},trial count : #{trial},,"
  Benchmark.benchmark( "", nil, "%u,") do |x|
    x.report( "" ){ trial.times{ src.dup.delete_if{ |x| x.nil? } } }
    x.report( "" ){ trial.times{ src.dup.keep_if{ |x| ! x.nil? } } }
    x.report( "" ){ trial.times{ src.dup.compact! } }
  end
  puts
end
3
3
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
3
3