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