Does this benchmark make sense?

F

Farhad Farzaneh

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)
 
B

Brian Candler

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.
 
F

Farhad Farzaneh

Brian said:
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...
 
B

Brian Candler

"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)

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 :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top