Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
require 'benchmark'
module A
end
class DefinedMethodStyle
def dont_bust_cache(*)
Object.new
nil
end
def bust_cache_class(*)
Class.new
nil
end
def bust_cache_extend(*)
Object.new.extend(A)
nil
end
end
class MethodMissingStyle
def _dont_bust_cache(*)
Object.new
nil
end
def _bust_cache_class(*)
Class.new
nil
end
def _bust_cache_extend(*)
Object.new.extend(A)
nil
end
def method_missing(method, *args)
if method == :bust_cache_class
_bust_cache_class(*args)
elsif method == :bust_cache_extend
_bust_cache_extend(*args)
elsif method == :dont_bust_cache
_dont_bust_cache(*args)
end
end
end
dms = DefinedMethodStyle.new
mms = MethodMissingStyle.new
n = 1_000_000
puts "Controls"
controls = Benchmark.bm do |bm|
bm.report("Object.new") { n.times { Object.new } }
bm.report("Class.new") { n.times { Class.new } }
bm.report("Object.new.extend(A)") { n.times { Object.new.extend(A) } }
end
puts "Tests"
tests = Benchmark.bm do |bm|
bm.report("defined methods, not busting cache") { n.times { |i| dms.dont_bust_cache(i) } }
bm.report("method_missing dispatch, not busting cache") { n.times { |i| mms.dont_bust_cache(i) } }
bm.report("defined methods, busting cache with Class.new") { n.times { |i| dms.bust_cache_class(i) } }
bm.report("method_missing dispatch, busting cache with Class.new") { n.times { |i| mms.bust_cache_class(i) } }
bm.report("defined methods, busting cache with Object.new.extend(A)") { n.times { |i| dms.bust_cache_extend(i) } }
bm.report("method_missing dispatch, busting cache with Object.new.extend(A)") { n.times { |i| mms.bust_cache_extend(i) } }
end
puts "Adjusted for overhead"
tests.each do |test|
puts test.label
control = controls[tests.find_index(test) / 2]
puts "Approximate method resolution time: #{test.real - control.real}"
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment