From: Patrick Ritchie Date: 2006-02-18T23:51:28+09:00 Subject: Re: define_method fun --Boundary_(ID_L3AcqXQCITH/XvT9LEPp0g) Content-type: text/plain; charset=ISO-8859-1; format=flowed Content-transfer-encoding: 7BIT Wow, that's impressive, why such huge difference? Cheers! Patrick >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) > > > > --Boundary_(ID_L3AcqXQCITH/XvT9LEPp0g)--