Project

General

Profile

Misc #10983

Why blocks make Ruby methods 439% slower ?

Added by Sega100500 (Сергей Е) over 4 years ago. Updated about 4 years ago.

Status:
Open
Priority:
Normal
Assignee:
-
[ruby-core:<unknown>]

Description

https://www.omniref.com/ruby/2.2.0/symbols/Proc/yield#annotation=4087638&line=711&hn=1

require 'benchmark/ips'

def block_call(&block)
  block.call
end

def just_yield
  yield
end

Benchmark.ips do |x|
  x.report("call") do
    block_call { 1 + 1 }
  end

  x.report("just yield") do
    just_yield { 1 + 1 }
  end

  x.compare!
end

I run on Ruby 2.2.1

Calculating -------------------------------------
                call    40.754k i/100ms
          just yield    69.031k i/100ms
-------------------------------------------------
                call    814.929k (± 4.0%) i/s -      4.075M
          just yield      2.871M (±25.1%) i/s -     12.909M

Comparison:
          just yield:  2871127.3 i/s
                call:   814929.3 i/s - 3.52x slower

History

#1

Updated by ko1 (Koichi Sasada) over 4 years ago

To capture local variables and so on (== an environment) for several frames is too heavy.

For example,

1.times{
  1.times{
    1.times{
      Proc.new{}
    }
  }
}

you need to capture all blocks' environments.
You don't need to capture environments only passing block.
So you need to say "passing block is faster" :)

BTW, I agree it is slow.
Improve the performance on this behavior will be great job.

Updated by nobu (Nobuyoshi Nakada) about 4 years ago

  • Description updated (diff)

Also available in: Atom PDF