Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a performance difference between `select` and `select!` when called on a Ruby hash?

hash = { 'mark' => 1, 'jane' => 1, 'peter' => 35 }.select {|k,v| v > 1}
#=> { 'peter' => 35 }

What if I have millions of keys - is there a difference between

hash = hash.select vs hash.select! ?

like image 296
dsp_099 Avatar asked Dec 04 '22 23:12

dsp_099


2 Answers

You can always do a little benchmark:

require 'benchmark'

# Creates a big hash in the format: { 1 => 1, 2 => 2 ... }
big_hash = 100_000.times.inject({}) { |hash, i| hash.tap { |h| h[i] = i }   }
Benchmark.bm do |bm|
   bm.report('select') { big_hash.select{ |k,v| v > 50 } }
   bm.report('select!') { big_hash.select!{ |k,v| v > 50 } }
end

         user       system     total     real
select   0.080000   0.000000   0.080000  (  0.088048)
select!  0.020000   0.000000   0.020000  (  0.021324)
like image 33
lcguida Avatar answered Apr 28 '23 14:04

lcguida


select! will perform better (I'll show the source for MRI, but it should be the same for the others).

The reason for this is that select needs to create a whole new Hash object, and will, for each entry in the hash, copy the entry - if the block succeeds.

On the other hand, select!, will, for each key, remove the value - if the block doesn't succeed - in-place (with no need for new object creation).

like image 87
Ven Avatar answered Apr 28 '23 14:04

Ven