Hello,
I was playing around with some Ruby features and benchmarked the
following, showing that making a class call using “self.method” is
faster than doing the same using “Classname.method”. Doesn’t make much
sense to me, but I’m not much of a benchmarker, so am hoping someone
will comment on this.
require ‘benchmark’
class VarEval
@@t=10
def self.t
@@t
end
def t
@@t
end
def self.time
n=5_000_000
Benchmark.bm do |x|
x.report(“direct”) { n.times { VarEval.t } }
x.report(“send”) { n.times { VarEval.send(:t) } }
x.report(“eval”) { n.times { eval("@@#{‘t’}") } }
end
end
def self.time2
n=5_000_000
Benchmark.bm do |x|
x.report(“direct”) { n.times { self.t } }
x.report(“send”) { n.times { self.send(:t) } }
x.report(“eval”) { n.times { eval("@@#{‘t’}") } }
end
end
def time
n=5_000_000
Benchmark.bm do |x|
x.report(“direct”) { n.times { self.class.t } }
x.report(“send”) { n.times { self.class.send(:t) } }
x.report(“eval”) { n.times { eval("@@#{‘t’}") } }
end
end
def sanity
puts “self.t=”,self.t
puts “self.class.t=”,self.class.t
puts %w{eval("@@#{‘t’}")},eval("@@#{‘t’}")
end
def self.sanity
puts “self.t=”,self.t
puts “VarEval.t=”,VarEval.t
puts %w{eval("@@#{‘t’}")},eval("@@#{‘t’}")
end
end
VarEval.sanity
VarEval.new.sanity
VarEval.time
VarEval.time2
VarEval.new.time
RESULTS in ORDER for
VarEval.time
VarEval.time2
VarEval.new.time
5_000_000 tries
user system total real
direct 2.230000 0.010000 2.240000 ( 2.313980)
send 2.830000 0.020000 2.850000 ( 2.919039)
eval 11.440000 0.050000 11.490000 ( 11.667510)
user system total real
direct 1.880000 0.010000 1.890000 ( 1.900675)
send 2.460000 0.010000 2.470000 ( 2.509326)
eval 11.440000 0.050000 11.490000 ( 11.688772)
user system total real
direct 2.360000 0.010000 2.370000 ( 2.395637)
send 2.970000 0.010000 2.980000 ( 3.011359)
eval 11.460000 0.050000 11.510000 ( 11.651057)
On Thu, May 31, 2007 at 08:12:34AM +0900, Farhad F. wrote:
I was playing around with some Ruby features and benchmarked the
following, showing that making a class call using “self.method” is
faster than doing the same using “Classname.method”.
By a tiny margin:
[self.x]
user system total real
direct 2.230000 0.010000 2.240000 ( 2.313980)
send 2.830000 0.020000 2.850000 ( 2.919039)
eval 11.440000 0.050000 11.490000 ( 11.667510)
…
[Klassname.x]
user system total real
direct 2.360000 0.010000 2.370000 ( 2.395637)
send 2.970000 0.010000 2.980000 ( 3.011359)
eval 11.460000 0.050000 11.510000 ( 11.651057)
Doesn’t make much sense to me
“self” doesn’t involve looking up a constant; “Klassname” does.
Brian C. wrote:
On Thu, May 31, 2007 at 08:12:34AM +0900, Farhad F. wrote:
I was playing around with some Ruby features and benchmarked the
following, showing that making a class call using “self.method” is
faster than doing the same using “Classname.method”.
By a tiny margin:
[self.x]
user system total real
direct 2.230000 0.010000 2.240000 ( 2.313980)
send 2.830000 0.020000 2.850000 ( 2.919039)
eval 11.440000 0.050000 11.490000 ( 11.667510)
…
[Klassname.x]
user system total real
direct 2.360000 0.010000 2.370000 ( 2.395637)
send 2.970000 0.010000 2.980000 ( 3.011359)
eval 11.460000 0.050000 11.510000 ( 11.651057)
Doesn’t make much sense to me
“self” doesn’t involve looking up a constant; “Klassname” does.
Thanks - actually, I believe that the correct comparison is:
[self.x]
user system total real
direct 1.880000 0.010000 1.890000 ( 1.900675)
send 2.460000 0.010000 2.470000 ( 2.509326)
eval 11.440000 0.050000 11.490000 ( 11.688772)
[Klassname.x]
user system total real
direct 2.230000 0.010000 2.240000 ( 2.313980)
send 2.830000 0.020000 2.850000 ( 2.919039)
eval 11.440000 0.050000 11.490000 ( 11.667510)
As expected, the eval is the same, but in both the send and the direct
call method, there is about a 0.35 second difference, which is a
substantial percentage. Seems to be an expensive symbol lookup
operation…
On Thu, May 31, 2007 at 04:13:26PM +0900, Farhad F. wrote:
user system total real
direct 2.230000 0.010000 2.240000 ( 2.313980)
send 2.830000 0.020000 2.850000 ( 2.919039)
eval 11.440000 0.050000 11.490000 ( 11.667510)
OK, checking again:
http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-talk/253666
So, “Klassname.t” and “self.class.t” are almost identical (where ‘self’
is
an instance of Klassname), but “Klassname.t” is slower than “self.t”
(where
‘self’ is Klassname).
OK, it’s a bit odd