Reduce memory usage by deduping strings and simplifying hash builder#477
Open
connorshea wants to merge 1 commit into
Open
Reduce memory usage by deduping strings and simplifying hash builder#477connorshea wants to merge 1 commit into
connorshea wants to merge 1 commit into
Conversation
Two small, independent allocation wins in the hot constructor path: * Build @value_hash with two direct passes over @values instead of Hash[map] + merge\!(Hash[map]), preserving the name-keys-win-on-collision precedence without the throwaway intermediate arrays and hashes. * For plain-symbol enums (no custom value), use -name.to_s so @value is a frozen, deduplicated String shared across every value of that name in the whole app, instead of a fresh String per value per class. It stays a plain (non-Value) String, so it's still safe to feed write_attribute. Class-definition-time allocations drop ~54%, and retained memory drops ~40 B/value (more where value names repeat across models). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This changeset was generated using Claude Code w/ Opus 4.8, but informed by usage in a production Rails app and tested and reviewed by me manually.
There are two changes here.
collapsing
@value_hashbuilding:Collapse the
@value_hashdouble-build (Hash[map]+merge!(Hash[map])) into two direct passes over@values, preserving the name key collision logic while removing some unnecessary allocation of throwaway intermediate arrays/hashes.string freezing:
For plain-symbol enums,
valuewas a fresh String duplicating theValue's own content, one per value per class. Using-name.to_sreturns a frozen, deduplicated String, so every value namedactiveacross the entire app can share a single object. It remains a plain String (not the Value subclass), so it is still safe to feedwrite_attribute. Custom values (e.g. in:{ admin: 1 }) are unchanged.Retained memory drops ~40 B/value with this, and more where value names repeat across models (this should be common in large rails apps especially).
Benchmarking
benchmark script
@value_hashtwo-pass build +-name.to_sstring dedup, measured by defining 5,000 classes whose six enum value names recur across all of them (the realistic case dedup targets). Whole-class construction,#textnever called.This isn't a massive win, but it does optimize things with no real downside that I can see.