---
title: "Ruby 2.5 added lazy proc allocation for block parameters"
description: "Ruby 2.5 added lazy proc allocation for block parameters"
canonical_url: "https://www.bigbinary.com/blog/ruby-2-5-added-lazy-proc-allocation-for-block-parameters"
markdown_url: "https://www.bigbinary.com/blog/ruby-2-5-added-lazy-proc-allocation-for-block-parameters.md"
---

# Ruby 2.5 added lazy proc allocation for block parameters

Ruby 2.5 added lazy proc allocation for block parameters

- Author: Amit Choudhary
- Published: May 22, 2018
- Categories: Ruby 2.5, Ruby

```ruby
irb> def greet
irb>   yield
irb> end
  => :greet
irb>
irb> def greet_with_welcome(&block)
irb>   puts 'Welcome'
irb>   greet(&block)
irb> end
  => :greet_with_welcome
irb> greet_with_welcome { p 'BigBinary' }
Welcome
"BigBinary"
  => "BigBinary"
```

In Ruby 2.4 when we pass a block to a method, which further passes to another
method, Ruby creates a new `Proc` object by the given block before passing this
proc to the another method.

This creates unnecessary objects even when the block parameter is not accessed.
It also creates a chain of `Proc` objects when the block parameter is passed
through various methods.

Proc creation is one a heavyweight operation because we need to store all local
variables (represented by Env objects in MRI internal) in the heap.

Ruby 2.5 introduced a lazy proc allocation. Ruby 2.5 will not create a Proc
object when passing a block to another method. Instead, it will pass the block
information. If the block is accessed somewhere else, then it creates a `Proc`
object by the given block.

This results in lesser memory allocation and faster execution.

#### Ruby 2.4

```ruby
irb> require 'benchmark'
  => true
irb> def greet
irb>   yield
irb> end
  => :greet
irb>
irb> def greet_with_welcome(&block)
irb>   puts 'Welcome'
irb>   greet(&block)
irb> end
  => :greet_with_welcome
irb>
irb> Benchmark.measure { 1000.times { greet_with_welcome { 'BigBinary' } } }
Welcome
Welcome
...
...
...
  => #<Benchmark::Tms:0x007fe6ab929de0 @label="", @real=0.022295999999187188, @cstime=0.0, @cutime=0.0, @stime=0.01, @utime=0.0, @total=0.01>
```

#### Ruby 2.5

```ruby
irb> require 'benchmark'
  => true
irb> def greet
irb>   yield
irb> end
  => :greet
irb>
irb> def greet_with_welcome(&block)
irb>   puts 'Welcome'
irb>   greet(&block)
irb> end
  => :greet_with_welcome
irb>
  irb> Benchmark.measure { 1000.times { greet_with_welcome { 'BigBinary' } } }
Welcome
Welcome
...
...
...
  => #<Benchmark::Tms:0x00007fa4400871b8 @label="", @real=0.004612999997334555, @cstime=0.0, @cutime=0.0, @stime=0.001524000000000001, @utime=0.0030690000000000023, @total=0.004593000000000003>
```

As we can see, there is considerable improvement in execution time when a block
param is passed in Ruby 2.5.

Here is the relevant [commit](https://github.com/ruby/ruby/commit/5ee9513a71)
and [discussion](https://bugs.ruby-lang.org/issues/14045).

## Links

- [Human page](https://www.bigbinary.com/blog/ruby-2-5-added-lazy-proc-allocation-for-block-parameters)
