Skip to content

Cache columns_digest on class#65

Merged
hmcguire-shopify merged 1 commit into
mainfrom
hm-xkxmmklzzwrkxmxz
Apr 28, 2026
Merged

Cache columns_digest on class#65
hmcguire-shopify merged 1 commit into
mainfrom
hm-xkxmmklzzwrkxmxz

Conversation

@hmcguire-shopify

@hmcguire-shopify hmcguire-shopify commented Mar 24, 2026

Copy link
Copy Markdown
Contributor

We previously improved the speed of columns_digest by not allocating an intermediate array. However, columns_digest is still very hot in our application (~15% of time spent inside MessagePack::Unpacker#full_unpack).

This commit caches columns_digest on the model class by hooking into schema loading. Since the value is calculated from a model's columns_hash, this ensures that if the schema is reloaded the value is recalculated.


The benchmark in #67 shows a 2x speedup on dumping and loading an Active Record

$ ruby --yjit benchmark/active-record-unpack.rb
-- create_table(:records)
   -> 0.0110s
=== dump ===
ruby 4.0.2 (2026-03-17 revision d3da9fec82) +YJIT +PRISM [arm64-darwin23]
Warming up --------------------------------------
        dump (after)    20.603k i/100ms
Calculating -------------------------------------
        dump (after)    204.449k (± 0.4%) i/s    (4.89 μs/i) -      1.030M in   5.038761s

Comparison:
       dump (before):   104609.9 i/s
        dump (after):   204449.0 i/s - 1.95x  faster


=== load ===
ruby 4.0.2 (2026-03-17 revision d3da9fec82) +YJIT +PRISM [arm64-darwin23]
Warming up --------------------------------------
        load (after)    22.651k i/100ms
Calculating -------------------------------------
        load (after)    226.690k (± 0.4%) i/s    (4.41 μs/i) -      1.155M in   5.096033s

Comparison:
       load (before):   110229.1 i/s
        load (after):   226689.9 i/s - 2.06x  faster

@hmcguire-shopify hmcguire-shopify force-pushed the hm-xkxmmklzzwrkxmxz branch 2 times, most recently from 0f1feaa to cead017 Compare March 24, 2026 03:28
We previously [improved][1] the speed of columns_digest by not
allocating an intermediate array. However, columns_digest is still very
hot in our application (~15% of time spent inside
MessagePack::Unpacker#full_unpack).

This commit caches columns_digest on the model class by hooking into
schema loading. Since the value is calculated from a model's
columns_hash, this ensures that if the schema is reloaded the value is
recalculated.

[1]: 5769fc2
@Chris911

Copy link
Copy Markdown
Member

@hmcguire-shopify @chrisbutcher any blockers to landing this?

@hmcguire-shopify hmcguire-shopify merged commit 78c2f91 into main Apr 28, 2026
37 checks passed
@hmcguire-shopify hmcguire-shopify deleted the hm-xkxmmklzzwrkxmxz branch April 28, 2026 18:00
@chrisbutcher

Copy link
Copy Markdown

🎉 🙏

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.

5 participants