Ruby hash initializing – why do you think you have a hash, but you have an array

We all use hashes and it seems, that there's nothing special about them. They are as dictionaries in Python, or any other similar structures available for multiple different languages. And that's more or less true. Although Ruby hashes are really special, because from time to time they really are... arrays.

You won't see that clearly until you either look into Ruby source code, or you benchmark it. Here is code and and results of my benchmark:

Benchmark

require 'benchmark'

GC.disable

ar = nil

100.times do |steps|
  d = Benchmark.measure {
    100000.times { ar = { a: 1, b: 2, c: 3, d: 4, e: 5, f: 6, g: 7, h: 8, i: 9, j: 10 } }
  }

  system("echo '#{ar.count}, #{d.real}' >> #{ar.count}.csv")
end

Benchmark results

hasharray

There's a huge disproportion between 6 and 7 elements. And that's the point where a Ruby "hashy array" becomes a real hash. To explain this, I will quote funny-falcon:

Investigation shows, that typical rails application allocates tons of small hashes. Up to 40% of whole allocated hashes never grows bigger than 1 element size.

That's the primary reason of this patch. Small arrays are faster and use less memory than hashes. If you want to see the code, here's a pull request with code that optimize arrays up to 6 elements.

Categories: Ruby, Software

Leave a Reply

Your email address will not be published. Required fields are marked *

*

Copyright © 2024 Closer to Code

Theme by Anders NorenUp ↑