Robert Dober
3/2/2007 9:34:00 AM
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