Created
July 21, 2011 07:52
-
-
Save fallwith/1096755 to your computer and use it in GitHub Desktop.
Ruby hash benchmarking
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'benchmark' | |
RUNS = 10_000 | |
OUTER_KEYS = 10 | |
INNER_STRUCTURES = 3 | |
INNER_KEYS = 5 | |
GC::Profiler.enable | |
def random_string(len=12) | |
len.times.inject(''){|s,n| s << ((rand(2)==1?65:97) + rand(25)).chr} | |
end | |
def random_symbol(len=12) | |
random_string(len).to_sym | |
end | |
def get_structure(type=:hash_with_symbols) | |
case type.to_sym | |
when :hash_with_indifferent_access then HashWithIndifferentAccess.new | |
else {} | |
end | |
end | |
def build_structure(type=:hash_with_symbols) | |
type = type.to_sym | |
structure = get_structure(type) | |
# Randomly put some key/val pairs into the structure at the top level | |
OUTER_KEYS.times do | |
key = type == :hash_with_strings ? random_string : random_symbol | |
structure[key] = random_string | |
end | |
# Randomly put some inner structures into the structure | |
INNER_STRUCTURES.times do | |
namespace = type == :hash_with_strings ? random_string : random_symbol | |
structure[namespace] = get_structure(type) | |
INNER_KEYS.times do | |
key = type == :hash_with_strings ? random_string : random_symbol | |
structure[namespace][key] = random_string | |
end | |
end | |
structure | |
end | |
puts "Benchmark:\n\n" | |
gc_results = {} | |
elapsed = {} | |
Benchmark.bmbm do |x| | |
x.report('Hash with symbols') do | |
start_time = Time.now | |
GC.start | |
RUNS.times{build_structure(:hash_with_symbols)} | |
gc_results[:hash_with_symbols] = GC::Profiler.result | |
elapsed[:hash_with_symbols] = Time.now - start_time | |
end | |
x.report('Hash with strings') do | |
start_time = Time.now | |
GC.start | |
RUNS.times{build_structure(:hash_with_strings)} | |
gc_results[:hash_with_strings] = GC::Profiler.result | |
elapsed[:hash_with_strings] = Time.now - start_time | |
end | |
x.report('Hash with indifferent access') do | |
start_time = Time.now | |
GC.start | |
RUNS.times{build_structure(:hash_with_indiffent_access)} | |
gc_results[:hash_with_indifferent_access] = GC::Profiler.result | |
elapsed[:hash_with_indifferent_access] = Time.now - start_time | |
end | |
end | |
puts "\n\nGC Stats:\n\n" | |
gc_results.each do |label,result| | |
puts label.upcase | |
lines = result.split("\n") | |
puts lines[1] | |
puts lines[-1] | |
puts | |
end | |
puts "\n\nElapsed times:\n\n" | |
elapsed.each do |label,time| | |
puts "#{label.upcase}: #{time} secs" | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Very useful! Thanks.