On 3/2/07, Joel VanderWerf <vjoel / path.berkeley.edu> wrote:
> Robert Dober wrote:
> > On 3/1/07, Niko <niko / kingtong.org> wrote:
> >> dblack / wobblini.net wrote:
> >> > Hi --
> >> >
> >> > On Thu, 1 Mar 2007, Niko wrote:
> >> >
> >> >>
> >> >> Hi all,
> >> >>
> >> >> I'm trying to define the missing block given in the context of the
> >> >> method to avoid the block_given? test on each iteration for yield
> >> call.
> >> >>
> >> >> def self.list_of_relationships(relations, source)
> >> >>   # missing_block_that_yield_would_call = lambda { || true } unless
> >> >> block_given?
> >> >>   relations.map do |relation|
> >> >>     if yield(peer = relation.send(source))
> >> >>       [peer.display_name, peer.id]
> >> >>     end
> >> >>   end.compact
> >> >> end
> >> >
> >> > You would want to do:
> >> >
> >> >   def self.list(relations,source,&block)
> >> >     block ||= lambda { true } # no need for empty ||
> >> >     relations.map do |relation|
> >> >       if block.call(peer = ....
> >> >
> >> > etc.  You'd have to do some benchmarks to find out whether the
> >> > slowdown from call is worse than the slowdown from block_given?.
> >> >
> >> >
> >> > David
> >> >
> >>
> >> it works like a charm
> >> i'll do some benchmarks to check the slowdown
> >>
> > they are bad unfortunately, I would not have thought of it, great
> > pointing at
> > that David.
> > ========================================================
> > require 'benchmark'
> >
> > def a1
> >     return true unless block_given?
> >     yield
> > end
> > def a2 &blk
> >     blk ||= proc{true}
> >     blk.call
> > end
> >
> >
> >    Benchmark.bmbm do |x|
> >      x.report("block_given?") {
> >          424242.times do
> >             a1 { 'hi' }
> >             a1
> >          end
> >           }
> >      x.report("&blk")  {
> >          424242.times do
> >             a2 { 'hi' }
> >             a2
> >         end
> >            }
> >    end
> > --------------->
> >
> > Rehearsal ------------------------------------------------
> > block_given?   1.280000   0.000000   1.280000 (  1.310912)
> > &blk           7.060000   0.020000   7.080000 ( 10.477620)
> > --------------------------------------- total: 8.360000sec
> >
> >                   user     system      total        real
> > block_given?   1.280000   0.000000   1.280000 (  1.284248)
> > &blk           7.090000   0.010000   7.100000 (  9.274008)
> >
> > ==================================================================
>
> That's not really fair to David's suggestion, though, since in the
Well I benchmarked my suggestion, not David's, probably made another
mistake in my "where to put the post".
However I felt that they were equivalent, do you agree?
> benchmark you put the loop around the block creation (so you are really
> stressing Proc.new).
Good point, I was missing that Proc.new was so costly and not #call !
But are we not unfair to #block_given? now?

Actually I tried to benchmark the difference between #call and #yield
only and one can see that
block_given? comes almost for free, as I have shown all too well #proc
is very expensive :(.

Therefore your results are pretty correct although you call
block_given way to often, but as it is so cheap..., did you know
maybe?

Thanks in any case for pointing out my error which was *big*.

Cheers
Robert

<snip>
-- 
We have not succeeded in answering all of our questions.
In fact, in some ways, we are more confused than ever.
But we feel we are confused on a higher level and about more important things.
-Anonymous