Skip to content

Instantly share code, notes, and snippets.

@lsdr
Created August 4, 2009 23:25
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 lsdr/162369 to your computer and use it in GitHub Desktop.
Save lsdr/162369 to your computer and use it in GitHub Desktop.
benchmarking method_missing
# http://www.jroller.com/dscataglini/entry/speeding_up_method_missing
require 'benchmark'
include Benchmark
class A
def foo(a, b, c)
1
end
end
class M1
def method_missing(key, *args, &block)
1
end
end
class M2
def method_missing(key, *args, &block)
if(key == :foo)
send :bar, args[0], args[1], args[2]
end
end
def bar(a,b,c)
1
end
end
class M3
def method_missing(key, *args, &block)
if(key.to_s.index("foo"))
send :bar, args[0], args[1], args[2]
end
end
def bar(a,b,c)
1
end
end
class M3A
def method_missing(key, *args, &block)
if(key.to_s.start_with?("foo"))
send :bar, args[0], args[1], args[2]
end
end
def bar(a,b,c)
1
end
end
class M4
def method_missing(key, *args, &block)
if(key.to_s =~ /foo/)
send :bar, args[0], args[1], args[2]
end
end
def bar(a,b,c)
1
end
end
class M4A
def method_missing(key, *args, &block)
if(key.to_s.match(/foo/))
send :bar, args[0], args[1], args[2]
end
end
def bar(a,b,c)
1
end
end
class M5
def method_missing(key, *args, &block)
if(key.to_s =~ /foo/)
self.class.class_eval <<-EOF, __FILE__, __LINE__
def #{key}(a, b, c)
bar a, b, c
end
EOF
send key, args[0], args[1], args[2]
end
end
def bar(a,b,c)
1
end
end
class M6
def method_missing(key, *args, &block)
if(key.to_s =~ /foo/)
self.class.class_eval <<-EOF, __FILE__, __LINE__
def #{key}(a, b, c)
1 # inlining the call
end
EOF
send key, args[0], args[1], args[2]
end
end
end
T = 1_000_000
a = A.new
m1 = M1.new
m2 = M2.new
m3 = M3.new
m3a = M3A.new
m4 = M4.new
m4a = M4A.new
m5 = M5.new
m6 = M6.new
Benchmark.bm(25) do |bm|
bm.report("static method"){T.times{a.foo(1,2,3)}}
bm.report("method missing baseline"){T.times{m1.foo(1,2,3)}}
bm.report("symbol equality"){T.times{m2.foo(1,2,3)}}
bm.report("index check"){T.times{m3.foo(1,2,3)}}
bm.report("start_with?"){T.times{m3a.foo(1,2,3)}}
bm.report("regular expression"){T.times{m4.foo(1,2,3)}}
bm.report("regexp matching"){T.times{m4a.foo(1,2,3)}}
bm.report("caching of method missing"){T.times{m5.foo(1,2,3)}}
bm.report("caching + inlining"){T.times{m6.foo(1,2,3)}}
end
mac [i686-darwin9.7.0], ruby 1.8.7-p174
user system total real
static method 4.050000 1.660000 5.710000 ( 5.925472)
method missing baseline 4.990000 1.670000 6.660000 ( 6.884910)
symbol equality 8.360000 2.510000 10.870000 ( 11.088755)
index check 9.920000 2.550000 12.470000 ( 12.714628)
start_with? 15.090000 3.420000 18.510000 ( 18.779444)
regular expression 11.990000 2.640000 14.630000 ( 15.101334)
regexp matching 12.570000 2.710000 15.280000 ( 15.497878)
caching of method missing 6.290000 2.560000 8.850000 ( 9.002898)
caching + inlining 4.030000 1.700000 5.730000 ( 5.892282)
mac [i386-darwin9.6.0], ruby 1.9.1-p0
user system total real
static method 0.190000 0.000000 0.190000 ( 0.190067)
method missing baseline 0.470000 0.010000 0.480000 ( 0.483549)
symbol equality 0.800000 0.000000 0.800000 ( 0.805389)
index check 1.250000 0.010000 1.260000 ( 1.267528)
start_with? 1.180000 0.000000 1.180000 ( 1.197280)
regular expression 2.800000 0.020000 2.820000 ( 2.862047)
regexp matching 3.010000 0.020000 3.030000 ( 3.228138)
caching of method missing 0.280000 0.000000 0.280000 ( 0.277588)
caching + inlining 0.180000 0.000000 0.180000 ( 0.184034)
ubuntu [i486-linux], ruby 1.8.7-p72
user system total real
static method 1.460000 0.270000 1.730000 ( 1.782399)
method missing baseline 2.130000 0.340000 2.470000 ( 2.474429)
symbol equality 4.440000 0.460000 4.900000 ( 4.920517)
index check 5.460000 0.400000 5.860000 ( 5.896596)
start_with? 8.470000 0.700000 9.170000 ( 9.205691)
regular expression 7.110000 0.560000 7.670000 ( 7.704200)
regexp matching 7.870000 0.500000 8.370000 ( 8.421248)
caching of method missing 2.280000 0.430000 2.710000 ( 2.718878)
caching + inlining 1.440000 0.240000 1.680000 ( 1.678930)
ubuntu [i686-linux], ruby 1.9.1-p0
user system total real
static method 0.400000 0.000000 0.400000 ( 0.407909)
method missing baseline 0.990000 0.000000 0.990000 ( 0.989299)
symbol equality 1.600000 0.000000 1.600000 ( 1.597277)
index check 2.760000 0.000000 2.760000 ( 2.761176)
start_with? 2.620000 0.000000 2.620000 ( 2.619946)
regular expression 5.210000 0.020000 5.230000 ( 5.212006)
regexp matching 5.670000 0.020000 5.690000 ( 5.683144)
caching of method missing 0.610000 0.000000 0.610000 ( 0.613747)
caching + inlining 0.400000 0.000000 0.400000 ( 0.410822)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment