I have a question:
Suppose we have a hash
hash = {:key1 => "value1", :key2 => "value2"}
what is more efficient way to access "value1" it multiple times.
Is it with directly
hash[:key1]
OR
val = hash[:key1]
CodePudding user response:
This is actually something you can check by yourself:
gem install benchmark-ips
require 'benchmark/ips'
hash = {key1: "value1", key2: "value2"}
Benchmark.ips do |x|
x.report("assign") { foo = hash[:key1] }
x.report("direct") { hash[:key1] }
end
and run it:
Warming up --------------------------------------
assign 1.644M i/100ms
direct 1.730M i/100ms
Calculating -------------------------------------
assign 15.884M (± 4.1%) i/s - 80.534M in 5.078824s
direct 16.811M (± 5.2%) i/s - 84.780M in 5.056902s
As expected, what you call direct (not assigning value to a variable) is slightly faster, but not by much (~6%)
You can learn more about this benchmarking tool here: https://github.com/evanphx/benchmark-ips
CodePudding user response:
I think the question is, if you need to use a value stored in a hash multiple times, say in a loop, is it faster to store the value in a variable or just access the value directly from the hash when it is needed.
Accessing the value in a hash is generally is O(1), but in the worst case can be O(n). In addition at the very least accessing the hash would require sending the key through the hashing function, so I think in general extracting the value once and then referring would be faster.
Here is a somewhat extreme case were the value is needed 1000 times, but you can see from the results of the built in benchmark module, accessing the variable is faster than accessing the hash. And since for this simple hash the access is almost certainty O(1), the difference is probably only due to the fact that the hashing function must be called on the key before getting the value.
require 'benchmark'
hash = {:key1 => "value1", :key2 => "value2"}
val = nil
Benchmark.bmbm do |x|
x.report { val = hash[:key1] }
end
puts "*****"
val = hash[:key1]
Benchmark.bmbm do |x|
x.report { 1000.times { val } }
x.report { 1000.times { hash[:key1] } }
end
Rehearsal ------------------------------------
0.000006 0.000002 0.000008 ( 0.000003)
--------------------------- total: 0.000008sec
user system total real
0.000006 0.000000 0.000006 ( 0.000004)
*****
Rehearsal ------------------------------------
0.000051 0.000000 0.000051 ( 0.000051)
0.000063 0.000000 0.000063 ( 0.000062)
--------------------------- total: 0.000114sec
user system total real
0.000048 0.000011 0.000059 ( 0.000054)
0.000082 0.000000 0.000082 ( 0.000077)