Home > OS >  Accessing hash value from hash directly VS from variable
Accessing hash value from hash directly VS from variable

Time:10-11

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)
  • Related