Created
August 4, 2009 23:25
-
-
Save lsdr/162369 to your computer and use it in GitHub Desktop.
benchmarking method_missing
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
# 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 |
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
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