Skip to content

Instantly share code, notes, and snippets.

@toch
Created August 20, 2015 08:58
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 toch/83fe8954477bfe4bfb9f to your computer and use it in GitHub Desktop.
Save toch/83fe8954477bfe4bfb9f to your computer and use it in GitHub Desktop.
Benchmarking Ruby's `method_missing` vs `define_method`
source "https://rubygems.org"
gem "benchmark-lab"
GEM
remote: https://rubygems.org/
specs:
benchmark-lab (0.0.1)
distribution
distribution (0.7.3)
PLATFORMS
ruby
DEPENDENCIES
benchmark-lab
###############################################################
n = 10
user system total real
method_missing - new object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
define_method - new object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
method_missing - existing object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
define_method - existing object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
The best "method_missing - new object " is not significantly (95%) better (total time).
###############################################################
n = 100
user system total real
method_missing - new object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
define_method - new object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
method_missing - existing object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
define_method - existing object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
The best "method_missing - new object " is not significantly (95%) better (total time).
###############################################################
n = 1000
user system total real
method_missing - new object [0.00,0.00,0.01] [0.00,0.00,0.00] [0.00,0.00,0.01] [0.00,0.00,0.00]
define_method - new object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
method_missing - existing object [0.00,0.00,0.01] [0.00,0.00,0.00] [0.00,0.00,0.01] [0.00,0.00,0.00]
define_method - existing object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
The best "method_missing - new object " is not significantly (95%) better (total time).
###############################################################
n = 10000
user system total real
method_missing - new object [0.03,0.03,0.04] [0.00,0.00,0.00] [0.03,0.03,0.04] [0.03,0.03,0.03]
define_method - new object [0.00,0.00,0.01] [0.00,0.00,0.00] [0.00,0.00,0.01] [0.00,0.00,0.00]
method_missing - existing object [0.03,0.03,0.04] [0.00,0.00,0.00] [0.03,0.03,0.04] [0.03,0.03,0.03]
define_method - existing object [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00] [0.00,0.00,0.00]
The best "define_method - existing object" is not significantly (95%) better (total time).
###############################################################
n = 100000
user system total real
method_missing - new object [0.33,0.34,0.35] [0.00,0.00,0.00] [0.33,0.34,0.35] [0.34,0.34,0.35]
define_method - new object [0.02,0.03,0.03] [0.00,0.00,0.00] [0.02,0.03,0.03] [0.03,0.03,0.03]
method_missing - existing object [0.31,0.33,0.33] [0.00,0.00,0.00] [0.31,0.33,0.33] [0.32,0.32,0.33]
define_method - existing object [0.01,0.02,0.02] [0.00,0.00,0.00] [0.01,0.02,0.02] [0.02,0.02,0.02]
The best "define_method - existing object" is significantly (95%) better (total time).
###############################################################
n = 1000000
user system total real
method_missing - new object [3.36,3.39,3.48] [0.00,0.00,0.00] [3.36,3.39,3.48] [3.37,3.41,3.48]
define_method - new object [0.26,0.26,0.27] [0.00,0.00,0.00] [0.26,0.26,0.27] [0.26,0.26,0.26]
method_missing - existing object [3.22,3.26,3.32] [0.00,0.00,0.00] [3.22,3.26,3.32] [3.24,3.26,3.32]
define_method - existing object [0.16,0.16,0.17] [0.00,0.00,0.00] [0.16,0.16,0.17] [0.16,0.16,0.17]
The best "define_method - existing object" is significantly (95%) better (total time).
require "benchmark/lab"
module Converted
def method_missing(method_sym, *arguments, &block)
if method_sym.to_s =~ /^(.+)_converted$/
self.send($1).to_f
else
super
end
end
end
module Value
def method_missing(method_sym, *arguments, &block)
if method_sym.to_s =~ /^(.+)_value$/
self.send($1) * 6.55957
else
super
end
end
end
class MethodMissed
include Converted
include Value
def some_attribute; 42; end
end
module DefineMethod
%i(some_attribute).each do |meth|
converted = define_method :"#{meth}_converted" do
send(meth).to_f
end
define_method :"#{converted}_value" do
send(meth) * 6.55957
end
end
end
class MethodDefined
include DefineMethod
def some_attribute; 42; end
end
nbr_of_samples = 20
[10, 100, 1_000, 10_000, 100_000, 1_000_000].each do |n|
puts "###############################################################"
puts "n = #{n}"
Benchmark.experiment(nbr_of_samples) do |x|
x.report("method_missing - new object ") do
n.times { MethodMissed.new.some_attribute_converted_value }
end
x.report("define_method - new object ") do
n.times { MethodDefined.new.some_attribute_converted_value }
end
x.report("method_missing - existing object") do
obj = MethodMissed.new
n.times { obj.some_attribute_converted_value }
end
x.report("define_method - existing object") do
obj = MethodDefined.new
n.times { obj.some_attribute_converted_value }
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment