Skip to content

Instantly share code, notes, and snippets.

@dscataglini
Created December 23, 2008 20:42
Show Gist options
  • Save dscataglini/39453 to your computer and use it in GitHub Desktop.
Save dscataglini/39453 to your computer and use it in GitHub Desktop.
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 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 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
m4 = M4.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("regular expression"){T.times{m4.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
# VERSION = 1.8.7-p72
# user system total real
# static method 0.295612 0.001624 0.297236 ( 0.321701)
# method missing baseline 0.567643 0.003783 0.571426 ( 0.628578)
# symbol equality 1.139567 0.006818 1.146385 ( 1.224589)
# index check 1.377338 0.008638 1.385976 ( 1.498267)
# regular expression 1.837666 0.012901 1.850567 ( 2.047866)
# caching of method missing 0.486595 0.002270 0.488865 ( 0.511950)
# caching + inlining 0.365636 0.001684 0.367320 ( 0.383320)
#
# VERSION = 1.9.0-5
# user system total real
# static method 0.287593 0.001519 0.289112 ( 0.308552)
# method missing baseline 0.552172 0.003834 0.556006 ( 0.604434)
# symbol equality 1.180124 0.005763 1.185887 ( 1.260123)
# index check 1.297773 0.007940 1.305713 ( 1.415773)
# regular expression 1.858729 0.012671 1.871400 ( 2.063151)
# caching of method missing 0.457304 0.002010 0.459314 ( 0.478891)
# caching + inlining 0.342845 0.002021 0.344866 ( 0.361926)
#
# VERSION = JRUBY
# user system total real
# static method 0.313397 0.002809 0.316206 ( 0.354470)
# method missing baseline 0.570404 0.004562 0.574966 ( 0.637837)
# symbol equality 1.082941 0.006078 1.089019 ( 1.173902)
# index check 1.256466 0.008117 1.264583 ( 1.395792)
# regular expression 1.627718 0.012748 1.640466 ( 1.872134)
# caching of method missing 0.471655 0.002542 0.474197 ( 0.501606)
# caching + inlining 0.362206 0.001912 0.364118 ( 0.383157)
#
# VERSION = rubinius 0.10.0 (362a70237)
# user system total real
# static method 0.479927 0.000000 0.479927 ( 0.479883)
# method missing baseline 1.024028 0.000000 1.024028 ( 1.024081)
# symbol equality 1.485076 0.000000 1.485076 ( 1.485110)
# index check 10.996608 0.000000 10.996608 ( 10.996657)
# regular expression 6.458455 0.000000 6.458455 ( 6.458505)
# caching of method missing 0.636479 0.000000 0.636479 ( 0.636501)
# caching + inlining Segmentation fault
#
# It's interesting for me looking at different implementations and see how things
# differ from one another. It really shows places where they need improvements.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment