先程「ary-[nil]
と ary.compact
」という記事( http://qiita.com/Nabetani/items/ba6b8eea61e03ce48df7 )を書いたんだけど、そういえば delete_if
とかもあったよな、と思い、調べてみたら意外な展開に。
まずはグラフ。縦軸は時間。対数目盛注意。
CRuby は、2.1.3。
JRuby は、1.17.15。
compact
がぐねぐねしているのは、誤差。
まず。
配列のサイズと繰り返す数の積が一定になるようにしているんで、計算量が変わらないことを期待しているんだけど、delete_if
はどんどん遅くなっている。
対数目盛なのでわかりにくいかもしれないけど、10倍以上遅くなっている。
keep_if
や compact!
は期待通り。なんだろうこれ。
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