检查 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?
还有其他明显更快的方法吗?
检查 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?
还有其他明显更快的方法吗?
Flatten 将导致您的代码重新分配一个新的、更大的缓冲区。您可以像这样跳过展平:
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)
让我们贪婪:
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)