Sam Kong wrote:
> Hello!
> 
> As you know, in Ruby, a block is not an object for some reasons, one of 
> which is performance.
> 
> def f
>   yield
> end
> 
> def g &blk
>   blk.call
> end
> 
> In g, a block is explicitly converted to a Proc object.
> What about in f?
> Is a block still converted to a Proc object implicitly?
> 
> If it's not converted, I understand the performance issue.
> However, it's always converted to a Proc object, I don't understand why 
> blocks improve performance just because they are not objects.
> 
> Can somebody explain this, please?

You've got the answer already, but it's interesting to see how much of a
difference it makes: (YMMV, of course.)

require 'benchmark'

def outer11(&bl)
  inner1(&bl)
end

def outer12(&bl)
  inner2(&bl)
end

def outer21
  inner1 {yield}
end

def outer22
  inner2 {yield}
end

def inner1(&bl)
  bl.call
end

def inner2
  yield
end

n = 100000

Benchmark.bmbm(10) do |rpt|
  rpt.report("outer11") do
    n.times {outer11{}}
  end

  rpt.report("outer12") do
    n.times {outer12{}}
  end

  rpt.report("outer21") do
    n.times {outer21{}}
  end

  rpt.report("outer22") do
    n.times {outer22{}}
  end
end

__END__

Output:

Rehearsal ---------------------------------------------
outer11     0.890000   0.010000   0.900000 (  0.894500)
outer12     0.370000   0.000000   0.370000 (  0.364880)
outer21     0.770000   0.000000   0.770000 (  0.776638)
outer22     0.170000   0.000000   0.170000 (  0.163393)
------------------------------------ total: 2.210000sec

                user     system      total        real
outer11     0.490000   0.000000   0.490000 (  0.491969)
outer12     0.400000   0.000000   0.400000 (  0.396264)
outer21     0.760000   0.000000   0.760000 (  0.764508)
outer22     0.160000   0.000000   0.160000 (  0.161982)


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