Skip to content

Instantly share code, notes, and snippets.

@fallwith
Created July 21, 2011 07:52
Show Gist options
  • Save fallwith/1096755 to your computer and use it in GitHub Desktop.
Save fallwith/1096755 to your computer and use it in GitHub Desktop.
Ruby hash benchmarking
#!/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
@fruchtose
Copy link

Very useful! Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment