fastruby / fast-ruby

:dash: Writing Fast Ruby :heart_eyes: -- Collect Common Ruby idioms.
https://github.com/fastruby/fast-ruby
5.67k stars 376 forks source link

Block vs Proc.new #78

Closed st0012 closed 6 years ago

st0012 commented 8 years ago

There are two ways to access block argument, one is using &block.

def test(&block)
  block
end

Another is using Proc.new inside the method.

def test
  Proc.new
end

And the benchmark result was

ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin15]
Calculating -------------------------------------
              &block    79.766k i/100ms
            Proc.new    76.432k i/100ms
-------------------------------------------------
              &block      1.601M (± 5.5%) i/s -      8.056M
            Proc.new      1.486M (± 4.5%) i/s -      7.414M

Comparison:
              &block:  1601064.1 i/s
            Proc.new:  1486080.7 i/s - 1.08x slower
winston commented 8 years ago

Hi. Pardon me, as I am helping @JuanitoFatas with the PRs.

Would this actually be more about comparing the instantiation of block vs Proc, rather than either being a parameter to a method? Just trying to dig into the atomic action that better defines this benchmark. Thanks!

JuanitoFatas commented 8 years ago

@st0012 In your example you are benchmarking: "accessing a block passed in" v.s. "instantiating Proc instance".

Should this benchmark be something like this?

require "benchmark/ips"

def block &block
  block.call
end

def proclike proc
  proc.call
end

Benchmark.ips do |x|
  x.report("&block") { block { 1 + 1 } }
  x.report("->") { proclike -> { 1 + 1 } }
  x.report("Lambda") { proclike lambda { 1 + 1 } }
  x.report("Proc.new") { proclike Proc.new { 1 + 1 } }
  x.compare!
end
carlos-contreras commented 7 years ago

I think that if the benefit is below 12% is not worth to mention, the README says so