Skip to content

Instantly share code, notes, and snippets.

@remigijusj
Last active August 29, 2015 14:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save remigijusj/a9e4273295073ae434e6 to your computer and use it in GitHub Desktop.
Save remigijusj/a9e4273295073ae434e6 to your computer and use it in GitHub Desktop.
comparison of deep data structures
require 'benchmark'
require 'date'
# from lib/core_ext/hash.rb
class Hash
def at(*path)
path.inject(self) do |ob, key|
ob.respond_to?(:each) ? ob[key] : nil
end
end
def set(*args)
value = args.pop
final = args.pop
point = args.inject(self) do |ob, key|
ob[key] ||= {}
end
point[final] = value
self # allows chaining
end
end
# new data structure: Hash keys are Hashes
# ex: data[{user_id: 1, shop_id: 1, date: Date.today}] = 7.5
class Bag
def initialize
@data = {}
end
def get(**args)
@data[args]
end
def set(val, **args)
@data[args] = val
end
end
COLUMNS = 10.times.map { |i| "column#{i}".to_sym }
SHOPS = 20.times.map { rand(1000) }
USERS = 50.times.map { rand(100000) }
DATES = Date.new(2015,4,1)..Date.new(2015,4,30)
def combinations(opt=nil)
COLUMNS.each do |col|
SHOPS.each do |shop|
USERS.each do |user|
DATES.each do |date|
if opt == :hash
yield({col: col, shop: shop, user: user, date: date})
else
yield [col, shop, user, date]
end
end
end
end
end
end
bag, flat, nest = nil, nil, nil
Benchmark.bm(12) do |x|
x.report("-> bag:") { bag = Bag.new; combinations(:hash) { |args| bag.set(42, **args) } }
x.report("-> flat:") { flat = Hash.new; combinations { |args| flat[args * ':'] = 42 } }
x.report("-> nested:") { nest = Hash.new; combinations { |args| nest.set(*args, 42) } }
x.report("<- bag:") { combinations(:hash) { |args| bag.get(**args) } }
x.report("<- flat:") { combinations { |args| flat[args * ':'] } }
x.report("<- nested:") { combinations { |args| nest.at(*args) } }
end
# user system total real
#-> bag: 3.797000 0.031000 3.828000 ( 3.857468)
#-> flat: 2.594000 0.063000 2.657000 ( 2.647608)
#-> nested: 2.547000 0.015000 2.562000 ( 2.568552)
#<- bag: 4.219000 0.031000 4.250000 ( 4.295042)
#<- flat: 2.281000 0.000000 2.281000 ( 2.286189)
#<- nested: 1.937000 0.000000 1.937000 ( 1.927114)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment