Skip to content

Replace generated Dirty method usage with targets - #113

Merged
byroot merged 1 commit into
byroot:masterfrom
Shopify:hm-urmsryyykymxyqtx
Sep 29, 2026
Merged

byroot merged 1 commit into
byroot:masterfrom
Shopify:hm-urmsryyykymxyqtx

Conversation

@hmcguire-shopify

Copy link
Copy Markdown

I've been looking into memory usage of my application, and, even with previous optimizations, generated attribute methods are still one of the largest individual sources of memory. To address this, I've been thinking through some solutions where we may be able to define methods lazily or even not at all (and just use method_missing). Especially for infrequently used methods, this seems like it could be a reasonable tradeoff.

This commit replaces usage of two of the less frequently used attribute methods with their underlying method call. Subjectively, I think the new code is better anyways since it avoids send and method name allocation, but it also ensures the methods don't get slower if we were to remove the Dirty method generation in the future.

I've been looking into memory usage of my application, and, even with
previous optimizations, generated attribute methods are still one of the
largest individual sources of memory. To address this, I've been
thinking through some solutions where we may be able to define methods
lazily or even not at all (and just use method_missing). Especially for
infrequently used methods, this seems like it could be a reasonable
tradeoff.

This commit replaces usage of two of the less frequently used attribute
methods with their underlying method call. Subjectively, I think the new
code is better anyways since it avoids `send` and method name
allocation, but it also ensures the methods don't get slower if we were
to remove the Dirty method generation in the future.
@hmcguire-shopify

Copy link
Copy Markdown
Author

Also happy to modernize/get CI working on newer versions of things if desired, it looks like #112 would fix tests for Rails 8.1 as advertised

@byroot

byroot commented Sep 29, 2026

Copy link
Copy Markdown
Owner

generated attribute methods are still one of the largest individual sources of memory. To address this, I've been thinking through some solutions where we may be able to define methods lazily or even not at all (and just use method_missing).

That's something I've been wondering for a while about Active Record itself. Surely, methods other than #attr, #attr= and perhaps attr? aren't called enough to justify precompilation?

we may be able to define methods lazily

Nah, this is just terrible for copy-on-write and post deploy latency. Either we define eagerly or we always go through method_missing but the pattern of compiling inside method_missing should be avoided.

@byroot
byroot merged commit 3dc5ac5 into byroot:master Sep 29, 2026
20 of 32 checks passed
@hmcguire-shopify
hmcguire-shopify deleted the hm-urmsryyykymxyqtx branch September 29, 2026 13:57
@hmcguire-shopify

Copy link
Copy Markdown
Author

Surely, methods other than #attr, #attr= and perhaps attr? aren't called enough to justify precompilation?

Yeah, that's basically what I found. Allegedly ~1000 uses of all other attribute methods across every model (based on searching, so could be more). Clearly if: :title_changed? is a nicer API for callbacks, but I'd be surprised if they were hotspots (and if they are, we could replace with the "less nice" API attribute_changed?(:title) to "restore" performance)

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.

3 participants