[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Re: define_method fun

Joel VanderWerf

2/18/2006 5:50:00 AM

Patrick Ritchie wrote:
> Hi All,
>
> I just setup the following in one of my classes, I'll let the code speak
> for itself:
>
> ["<", "<=", ">", ">=", "==", "<=>"].each do |op|
> define_method(op) { |comparison| eval "#{self.order} #{op}
> #{comparison.order}" }
> end
>
> Ruby continues to impress me with it's ability to do so much in so few
> amazing readable lines of code.
>
> Are their any good reasons not to declare my op methods this way? Is
> their an even more efficient way to achieve the same effect?

It helps to pull the eval out of the define_method:


module Order
attr_reader :order
def initialize order
@order = order
end
end

class EvalInside
include Order
["<", "<=", ">", ">=", "==", "<=>"].each do |op|
define_method(op) { |comparison| eval "#{self.order} #{op}
#{comparison.order}" }
end
end

class EvalOutside
include Order
["<", "<=", ">", ">=", "==", "<=>"].each do |op|
eval "define_method(:#{op}) { |comparison| self.order #{op}
comparison.order }"
end
end

require 'benchmark'

inside = []
outside = []
1000000.times do |i|
order = rand(1)
inside << EvalInside.new(i)
outside << EvalOutside.new(i)
end

Benchmark.bmbm do |bm|
bm.report("eval inside") do
inside.sort
end

bm.report("eval outside") do
outside.sort
end
end


Rehearsal ------------------------------------------------
eval inside 17.280000 0.030000 17.310000 ( 18.088599)
eval outside 2.170000 0.010000 2.180000 ( 2.254999)
-------------------------------------- total: 19.490000sec

user system total real
eval inside 17.260000 0.010000 17.270000 ( 17.873053)
eval outside 2.150000 0.010000 2.160000 ( 2.248230)


--
vjoel : Joel VanderWerf : path berkeley edu : 510 665 3407


3 Answers

Dominik Bathon

2/18/2006 4:16:00 PM

0

On Sat, 18 Feb 2006 06:49:37 +0100, Joel VanderWerf
<vjoel@path.berkeley.edu> wrote:

> Patrick Ritchie wrote:
>> Hi All,
>>
>> I just setup the following in one of my classes, I'll let the code speak
>> for itself:
>>
>> ["<", "<=", ">", ">=", "==", "<=>"].each do |op|
>> define_method(op) { |comparison| eval "#{self.order} #{op}
>> #{comparison.order}" }
>> end
>>
>> Ruby continues to impress me with it's ability to do so much in so few
>> amazing readable lines of code.
>>
>> Are their any good reasons not to declare my op methods this way? Is
>> their an even more efficient way to achieve the same effect?
>
> It helps to pull the eval out of the define_method:

Or using no eval at all:

> module Order
> attr_reader :order
> def initialize order
> @order = order
> end
> end
>
> class EvalInside
> include Order
> ["<", "<=", ">", ">=", "==", "<=>"].each do |op|
> define_method(op) { |comparison| eval "#{self.order} #{op}
> #{comparison.order}" }
> end
> end
>
> class EvalOutside
> include Order
> ["<", "<=", ">", ">=", "==", "<=>"].each do |op|
> eval "define_method(:#{op}) { |comparison| self.order #{op}
> comparison.order }"
> end
> end

class NoEval
include Order
[:<, :<=, :>, :>=, :==, :<=>].each do |op|
define_method(op) { |comparison| self.order.send(op, comparison.order)
}
end
end

> require 'benchmark'
>
> inside = []
> outside = []
noeval = []
400000.times do |i|
> order = rand(1)
> inside << EvalInside.new(i)
> outside << EvalOutside.new(i)
noeval << NoEval.new(i)
> end
>
> Benchmark.bmbm do |bm|
> bm.report("eval inside") do
> inside.sort
> end
>
> bm.report("eval outside") do
> outside.sort
> end

bm.report("no eval") do
noeval.sort
end
> end

Rehearsal ------------------------------------------------
eval inside 19.310000 0.060000 19.370000 ( 19.500018)
eval outside 1.940000 0.010000 1.950000 ( 1.951829)
no eval 2.600000 0.010000 2.610000 ( 2.626695)
-------------------------------------- total: 23.930000sec

user system total real
eval inside 18.690000 0.080000 18.770000 ( 18.950481)
eval outside 1.920000 0.000000 1.920000 ( 1.940485)
no eval 2.010000 0.000000 2.010000 ( 2.028688)


Dominik


MenTaLguY

2/18/2006 6:48:00 PM

0

On Sat, 2006-02-18 at 23:51 +0900, Patrick Ritchie wrote:
> Wow, that's impressive, why such huge difference?

eval-ing (especially a string) is expensive, basically.

If you move the eval outside the method body, it means you only pay that
cost once (when defining the method), rather than every time the method
is run.

-mental



Art Harris

4/29/2010 10:45:00 PM

0

Ray wrote:

> Wow, as a long time Shep fan I'm amazed I had not heard about this
> before. I used to listen to his show on 660 AM out of NYC (transistor
> radio under the covers after bed time, just like in the movies) and
> thought I knew all about him.
>

Hey, I did the same thing from my house in Queens. But he was on WOR
710.

I recall him talking about the Beatles on one of his radio shows. I
don't recall the reason he was with the Beatles (I guess it was this
Playboy gig). In particular, he didn't like John telling him, "get me
some cigarettes." He told John he'd be glad to get them if he asked,
but didn't like being told. After that he and John got along ok
(according to Shep).

Remember the Saturday shows broadcast from the Limelight?

Art Harris

--

All follow-ups are directed to the newsgroup rec.music.beatles.moderated.
If your follow-up more properly belongs in the unmoderated newsgroup, please
change your headers appropriately. -- the moderators
--