よたらぼ
自分の興味の赴くままにIT技術系のネタを取りとめもなくメモっています。
Ruby言語やLinuxのネタが多いです。

July 28, 2007 [おもひで]

[Ruby] hash.keys.include?とhash.has_key?

Ruby-GetText-Package-1.10.0で実施したメッセージキャッシュの実装の中に、キャッシュがあるかないかの判定でhash.has_key?(key)と書けば良いところをhash.keys.include?(key)と書いてあるところが2ヶ所あり、これがパフォーマンス(レポートではCPU使用率)にかなり影響を与えているというレポートがあった

もし、同様の問題を抱えている人がいたら、Ruby-GetText-PackageのCVS版を使うか、lib/gettext.rbでkeys.include?と記述しているところをhas_key?と置換してみてほしい。

実際にベンチマークをとってみると相当差がある。毎回配列生成するんだからそりゃそうだよなぁ。なんでkeys.include?なんて書いたんだろ(^^;)。

require 'benchmark'
 
hash = {}
5000.times{|i| hash[i] = "foo#{i}"}
 
Benchmark.bm(20){|x|
  x.report("hash.keys.include?"){ 10000.times{|i|
    hash.keys.include?(i)
  } }
  x.report("hash.has_key?"){ 10000.times{|i|
    hash.has_key?(i)
  } }
}

結果

% ruby test.rb
                          user     system      total        real
hash.keys.include?    5.230000   0.000000   5.230000 (  5.232516)
hash.has_key?         0.000000   0.000000   0.000000 (  0.003292)

そうそう、レポート先では実際にRuby-GetText-Packageを使ってそれなりの規模のサイトを構築・運用してるらしい。実際に使ってくれてるって聞くとやっぱりうれしいよね。


編集