From: Nobuyoshi Nakada Date: 2007-08-21T10:43:25+09:00 Subject: [ruby-list:43887] Re: Hashへの生成順は保障されないのか? --Multipart_Tue_Aug_21_10:43:30_2007-1 Content-Type: text/plain; charset=ISO-2022-JP なかだです。 At Tue, 21 Aug 2007 07:46:20 +0900, Yukihiro Matsumoto wrote in [ruby-list:43879]: > 実は私自身はHashの順序の保存については積極的に反対しているわ > けではないのです。しかし、 > > * 一般的にはHashの順序が保存されない > * どの順序が最適かは実は一意に決まらない(ような気がする) 「どの順序」と選べるほど選択肢はないような気がするのですが。 > * 順序の保存によってHashの効率が下がるのはうれしくない [ruby-dev:24569]を1.9最新用に直して、Hal Fultonから送られてきた ベンチマークを試してみました。 http://www.rubyist.net/~nobu/ruby/ordered-hash-1.9.diff http://www.rubyist.net/~nobu/ruby/ordered-hash-1.8.diff 予想通りdeleteがやや遅くなっていますが、思ったほどの影響はないよ うです。逆にeachやsort_byが速くなっているのは、二重配列から単純 なdouble linked listをたどるようになっているのが大きいのかもしれ ません。 前 add to empty hash 0.650000 0.010000 0.660000 ( 0.654691) add to hash with 100000 elements 0.710000 0.020000 0.730000 ( 0.730761) each_key with 200000 elements 0.050000 0.000000 0.050000 ( 0.053228) keys.sort_by.each, 200000 elements 1.150000 0.000000 1.150000 ( 1.159369) delete 100000 times, non-existing key 0.040000 0.000000 0.040000 ( 0.034815) delete 100000 times, existing keys 0.260000 0.000000 0.260000 ( 0.256023) include? 100000 times, non-existing key 0.050000 0.000000 0.050000 ( 0.046105) include? 100000 times, existing keys 0.230000 0.000000 0.230000 ( 0.225641) clear hash with 100000 elements 0.030000 0.000000 0.030000 ( 0.037633) 後 user system total real add to empty hash 0.550000 0.020000 0.570000 ( 0.558828) add to hash with 100000 elements 0.620000 0.010000 0.630000 ( 0.636749) each_key with 200000 elements 0.040000 0.000000 0.040000 ( 0.043783) keys.sort_by.each, 200000 elements 0.270000 0.010000 0.280000 ( 0.276364) delete 100000 times, non-existing key 0.030000 0.000000 0.030000 ( 0.035522) delete 100000 times, existing keys 0.270000 0.000000 0.270000 ( 0.265942) include? 100000 times, non-existing key 0.030000 0.000000 0.030000 ( 0.028704) include? 100000 times, existing keys 0.190000 0.000000 0.190000 ( 0.193877) clear hash with 100000 elements 0.040000 0.000000 0.040000 ( 0.035513) --Multipart_Tue_Aug_21_10:43:30_2007-1 Content-Type: text/x-ruby; charset=US-ASCII Content-Disposition: attachment; filename="bm_hash.rb" Content-Transfer-Encoding: 7bit # Hash benchmarking suite # by Ryan Leavengood require 'benchmark' class SymbolGen def initialize(value='aaaaaaaa') @value = value end def generate result = @value.intern @value = @value.succ result end end if $0 == __FILE__ sg = SymbolGen.new h = {} iterations = 100000 Benchmark.bm(40) do |bx| block = proc { h[sg.generate] = sg.generate } bx.report("add to empty hash") { iterations.times &block } bx.report("add to hash with #{iterations} elements") { iterations.times &block } bx.report("each_key with #{2*iterations} elements") { h.each_key {|key|} } bx.report("keys.sort_by.each, #{2*iterations} elements") { h.keys.sort_by{|k| k.to_s}.each {|key|} } bx.report("delete #{iterations} times, non-existing key") { iterations.times { h.delete(:not_a_key) } } sg2 = SymbolGen.new bx.report("delete #{iterations} times, existing keys") { iterations.times { h.delete(sg2.generate); sg2.generate } } bx.report("include? #{iterations} times, non-existing key") { iterations.times { h.include?(:not_a_key) } } bx.report("include? #{iterations} times, existing keys") { iterations.times { h.include?(sg2.generate); sg2.generate } } bx.report("clear hash with #{iterations} elements") { h.clear } end end --Multipart_Tue_Aug_21_10:43:30_2007-1 Content-Type: text/plain; charset=ISO-2022-JP -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦 --Multipart_Tue_Aug_21_10:43:30_2007-1--