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 
benchmark you put the loop around the block creation (so you are really 
stressing Proc.new). This seems closer to the original example:


require 'benchmark'

def a1 n
   n.times do
     if block_given?
       yield
     end
   end
end

def a2 n, &blk
   blk ||= proc{true}
   n.times do
     blk.call
   end
end


Benchmark.bmbm do |x|
   x.report("block_given?") {
     a1(424242) { 'hi' }
   }
   x.report("&blk")  {
     a2(424242) { 'hi' }
   }
end



Rehearsal ------------------------------------------------
block_given?   0.633333   0.000000   0.633333 (  0.389330)
&blk           1.050000   0.000000   1.050000 (  0.622025)
--------------------------------------- total: 1.683333sec

                    user     system      total        real
block_given?   0.650000   0.000000   0.650000 (  0.384855)
&blk           1.033333   0.000000   1.033333 (  0.621509)



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