0

Rubyハッシュオブジェクトのすべてのキーが空の配列を指しているかどうかを確認する最も速い方法は何ですか?

私の現在のアプローチ:

h = {"a" => [1,2,3], "b" => []}
var = "something" if h.values.flatten.size > 0

別のアプローチ:

h = {"a" => [1,2,3], "b" => []}
var = "something" if h.values.flatten.empty?

他に明らかに速い方法はありますか?

4

2 に答える 2

4

フラット化すると、コードが新しい、より大きなバッファーを再割り当てします。次のようにフラット化をスキップできます。

h.values.all? &:empty?

ベンチマーク:

Benchmark.measure {100000.times{ h.values.all? &:empty? }}
# =>   0.100000   0.000000   0.100000 (  0.096073)

Benchmark.measure {100000.times{ h.values.flatten.empty? }}
# =>   0.140000   0.000000   0.140000 (  0.143457)

以下を含むより大きなベンチマークh.all? {|_,v| v.empty?}

h = {}
(1...10000).each {|i| h[i] = []}  # Pathological case

Benchmark.measure {1000.times{ h.values.flatten.empty? }}
# =>   1.880000   0.000000   1.880000 (  1.882853)
Benchmark.measure {1000.times{ h.values.all? &:empty? }}
# =>   1.750000   0.000000   1.750000 (  1.748415)
Benchmark.measure {1000.times{ h.all? {|_,v| v.empty?} }}
# =>   4.140000   0.000000   4.140000 (  4.137548)
于 2012-07-28T05:47:14.893 に答える
1

貪欲になりましょう:

all_empty = true

h.each_value do |value|
  unless value.empty?
    all_empty = false
    break
  end
end

ベンチマーク:

h = {}
(1...10000).each {|i| h[i] = []}

Benchmark.measure {1000.times{ h.values.flatten.empty? }}
=>   2.020000   0.000000   2.020000 (  2.026274)
Benchmark.measure {1000.times{ h.values.all? &:empty? }}
=>   1.750000   0.000000   1.750000 (  1.750908)
Benchmark.measure {1000.times{ h.all? {|_,v| v.empty?} }}
=>   3.570000   0.000000   3.570000 (  3.570945)
Benchmark.measure {1000.times{ <code above> }} # Worst case
=>   1.530000   0.000000   1.530000 (  1.529857)
于 2012-07-28T06:02:49.510 に答える