Last active
December 25, 2015 10:38
-
-
Save gamache/6962565 to your computer and use it in GitHub Desktop.
Code to test relative performace penalty of invalidating the MRI Ruby method cache, versus performing method resolution manually via method_missing. (Edit 1: pinpoint the overhead of Class.new by comparing it to a trivial Object#extend; thanks @joshjordanwhat! Edit 2: added optional warm-up to make JRuby benchmarks make more sense.)
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
require 'benchmark' | |
module A; end | |
class DefinedMethodStyle | |
def bust_cache_class(*); Class.new; nil end | |
def bust_cache_extend(*); Object.new.extend(A); nil end | |
def dont_bust_cache(*); Object.new; nil end | |
end | |
class MethodMissingStyle | |
def _bust_cache_class(*); Class.new; nil end | |
def _bust_cache_extend(*); Object.new.extend(A); nil end | |
def _dont_bust_cache(*); Object.new; nil end | |
def method_missing(method, *args) | |
case method | |
when :bust_cache_class then _bust_cache_class(*args) | |
when :bust_cache_extend then _bust_cache_extend(*args) | |
when :dont_bust_cache then _dont_bust_cache(*args) | |
end | |
end | |
end | |
dms = DefinedMethodStyle.new | |
mms = MethodMissingStyle.new | |
n = 1_000_000 | |
if ENV['WARM_UP'] # this helps with JRuby benchmarking | |
puts "Warming up.\n" | |
for i in 1..n | |
dms.bust_cache_extend(i); dms.bust_cache_class(i); dms.dont_bust_cache(i) | |
mms.bust_cache_extend(i); mms.bust_cache_class(i); mms.dont_bust_cache(i) | |
end | |
end | |
Benchmark.bm do |bm| | |
puts "\n defined methods, not busting cache:" | |
bm.report { for i in 1..n; dms.dont_bust_cache(i) end } | |
puts "\n method_missing dispatch, not busting cache:" | |
bm.report { for i in 1..n; mms.dont_bust_cache(i) end } | |
puts "\n defined methods, busting cache with trivial Object#extend:" | |
bm.report { for i in 1..n; dms.bust_cache_extend(i) end } | |
puts "\n defined methods, busting cache with Class.new:" | |
bm.report { for i in 1..n; dms.bust_cache_class(i) end } | |
puts "\n method_missing dispatch, busting cache with trivial Object#extend:" | |
bm.report { for i in 1..n; mms.bust_cache_extend(i) end } | |
puts "\n method_missing dispatch, busting cache with Class.new:" | |
bm.report { for i in 1..n; mms.bust_cache_class(i) end } | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment