Skip to content

Instantly share code, notes, and snippets.

@tribalvibes
Created August 3, 2011 19:42
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tribalvibes/1123584 to your computer and use it in GitHub Desktop.
Save tribalvibes/1123584 to your computer and use it in GitHub Desktop.
calling ruby method defined via define_method is 50% slower than via class_eval
# define benchmark from:
#http://www.mathewabonyi.com/articles/2007/01/11/surprise-10min-benchmark-eval-class_eval-instance_eval-define_method-bind#trackbacks
# but we're interested in the speed of calling the method not only defining it
# results with ruby 1.9.2-p180 on mbp i7
require 'benchmark'
class A; def meth1; true; end; end
# defining using eval/class/instance
str = "def meth2; true; end"
a_binding = A.send(:binding)
# proc for class/instance
proc1 = Proc.new { def meth2; true; end }
# proc for define_method
$proc2 = Proc.new { true }
# unbound method for bind
um = A.instance_method(:meth1)
# number of iterations
n = 300000 # * 600
Benchmark.bm(22) do |x|
x.report('instance_eval/str') do
for i in 1..n; A.instance_eval(str); end
end
x.report('class_eval/str') do
for i in 1..n; A.class_eval(str); end
end
x.report('eval/str') do
for i in 1..n; eval(str, a_binding); end
end
x.report('define_method/class') do
for i in 1..n; class A; define_method(:meth2, &$proc2); end; end
end
x.report('define_method/send') do
for i in 1..n; A.send(:define_method, :meth2, &$proc2); end
end
x.report('def/unbind/bind') do
for i in 1..n
class A; def meth2; true; end; end
A.instance_method(:meth2).bind(A.new)
end
end
x.report('instance_eval/proc') do
for i in 1..n; A.instance_eval(&proc1); end
end
x.report('class_eval/proc') do
for i in 1..n; A.class_eval(&proc1); end
end
x.report('def') do
for i in 1..n; class A; def meth2; true; end; end; end
end
x.report('method/bind') do
for i in 1..n; um.bind(A.new); end
end
end
# user system total real
# instance_eval/str 5.720000 0.030000 5.750000 ( 5.807193)
# class_eval/str 5.800000 0.030000 5.830000 ( 5.893954)
# eval/str 5.780000 0.030000 5.810000 ( 5.860869)
# define_method/class 0.980000 0.010000 0.990000 ( 0.990898)
# define_method/send 0.950000 0.030000 0.980000 ( 0.979376)
# def/unbind/bind 1.340000 0.020000 1.360000 ( 1.378884)
# instance_eval/proc 1.040000 0.010000 1.050000 ( 1.100660)
# class_eval/proc 0.910000 0.010000 0.920000 ( 0.919074)
# def 0.950000 0.010000 0.960000 ( 0.959918)
# method/bind 0.190000 0.000000 0.190000 ( 0.198555)
puts "Calling defined method:"
class B; def meth1; true; end; end
# defining using eval/class/instance
str = "def meth2; true; end"
str3 = "def meth3; true; end"
B_binding = B.send(:binding)
# proc for class/instance
proc1 = Proc.new { def meth7; true; end }
# proc for define_method
$proc2 = Proc.new { true }
# unbound method for bind
um = B.instance_method(:meth1)
# number of iterations
n = 30000000 # * 600
Benchmark.bm(22) do |x|
x.report('instance_eval/str') do
B.instance_eval(str)
for i in 1..n; B.meth2; end
end
x.report('class_eval/str') do
B.class_eval(str)
b = B.new
for i in 1..n; b.meth2; end
end
# x.report('eval/str') do
# eval(str3, B_binding);
# b = B.new
# for i in 1..n; b.meth3; end
# end
x.report('define_method/class') do
class B; define_method(:meth4, &$proc2); end
b = B.new
for i in 1..n; b.meth4; end
end
x.report('define_method/send') do
B.send(:define_method, :meth5, &$proc2);
b = B.new
for i in 1..n; b.meth5; end
end
x.report('def/unbind/bind') do
class B; def meth6; true; end; end
B.instance_method(:meth6).bind(B.new)
b = B.new
for i in 1..n; b.meth6; end
end
x.report('instance_eval/proc') do
B.instance_eval(&proc1);
for i in 1..n; B.meth7; end
end
x.report('class_eval/proc') do
B.class_eval(&proc1);
b = B.new
for i in 1..n; b.meth7; end
end
x.report('def') do
class B; def meth8; true; end; end;
b = B.new
for i in 1..n; b.meth8; end
end
# x.report('method/bind') do
# um.bind(A.new);
# for i in 1..n; end
# end
# Calling defined method:
# user system total real
# instance_eval/str 3.790000 0.010000 3.800000 ( 3.832410)
# class_eval/str 3.780000 0.020000 3.800000 ( 3.816410)
# define_method/class 5.990000 0.020000 6.010000 ( 6.046599)
# define_method/send 6.090000 0.030000 6.120000 ( 6.156742)
# def/unbind/bind 3.830000 0.020000 3.850000 ( 3.889191)
# instance_eval/proc 3.760000 0.010000 3.770000 ( 3.786376)
# class_eval/proc 3.840000 0.020000 3.860000 ( 3.885466)
# def 4.410000 0.020000 4.430000 ( 4.654724)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment