Skip to content

Speed up immediate unpack when freeze: true by 10%#396

Merged
byroot merged 2 commits into
msgpack:masterfrom
skipkayhil:hm-skokvxlqtrxvuppu
Jun 28, 2026
Merged

Speed up immediate unpack when freeze: true by 10%#396
byroot merged 2 commits into
msgpack:masterfrom
skipkayhil:hm-skokvxlqtrxvuppu

Conversation

@skipkayhil

Copy link
Copy Markdown
Contributor

Rename object_complete_symbol -> frozen

To use with other, non-symbol, pre-frozen objects.


Speed up immediate unpack when freeze: true by 10%

Since immediates are already frozen, we can skip over "maybe freeze"
behavior completely for those types.

ruby 4.0.2 (2026-03-17 revision d3da9fec82) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
             control     5.437k i/100ms
       frozen before     4.733k i/100ms
Calculating -------------------------------------
             control     54.830k (± 1.8%) i/s   (18.24 μs/i) -    277.287k in   5.057252s
       frozen before     49.078k (± 1.9%) i/s   (20.38 μs/i) -    246.116k in   5.014762s

Comparison:
 frozen after:    55009.0 i/s
      control:    54829.6 i/s - same-ish: difference falls within error
frozen before:    49078.3 i/s - 1.12x  slower
require 'msgpack'
require 'benchmark/ips'

data = []
100.times do
  data << rand(0..127)
  data << -rand(0..30)
  data << nil
  data << true
  data << false
  data << rand(0..65535)
end

packed = MessagePack.pack(data)

up_ctl = MessagePack::Unpacker.new(freeze: false)
up_frz = MessagePack::Unpacker.new(freeze: true)

Benchmark.ips do |x|
  x.report("control") { up_ctl.feed(packed); up_ctl.read }

  x.report("frozen #{ENV.fetch("STAGE", "after")}") { up_frz.feed(packed); up_frz.read }

  x.save!("/tmp/msgpack_un_freeze")

  x.compare!
end

To use with other, non-symbol, pre-frozen objects.
Since immediates are already frozen, we can skip over "maybe freeze"
behavior completely for those types.

```
ruby 4.0.2 (2026-03-17 revision d3da9fec82) +YJIT +PRISM [x86_64-linux]
Warming up --------------------------------------
             control     5.437k i/100ms
       frozen before     4.733k i/100ms
Calculating -------------------------------------
             control     54.830k (± 1.8%) i/s   (18.24 μs/i) -    277.287k in   5.057252s
       frozen before     49.078k (± 1.9%) i/s   (20.38 μs/i) -    246.116k in   5.014762s

Comparison:
 frozen after:    55009.0 i/s
      control:    54829.6 i/s - same-ish: difference falls within error
frozen before:    49078.3 i/s - 1.12x  slower
```

```ruby
require 'msgpack'
require 'benchmark/ips'

data = []
100.times do
  data << rand(0..127)
  data << -rand(0..30)
  data << nil
  data << true
  data << false
  data << rand(0..65535)
end

packed = MessagePack.pack(data)

up_ctl = MessagePack::Unpacker.new(freeze: false)
up_frz = MessagePack::Unpacker.new(freeze: true)

Benchmark.ips do |x|
  x.report("control") { up_ctl.feed(packed); up_ctl.read }

  x.report("frozen #{ENV.fetch("STAGE", "after")}") { up_frz.feed(packed); up_frz.read }

  x.save!("/tmp/msgpack_un_freeze")

  x.compare!
end
```
@skipkayhil skipkayhil changed the title Speed up immediate unpack when freeze: true Speed up immediate unpack when freeze: true by 10% Jun 27, 2026
@byroot byroot merged commit b8d2338 into msgpack:master Jun 28, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants