Skip to content

[perf] Reuse rebuilt ClassReflection by class content hash to stop memory growth on class refresh - #8731

Merged
samsonasik merged 2 commits into
mainfrom
add-benchmark-class-reflection
Oct 20, 2026
Merged

samsonasik merged 2 commits into
mainfrom
add-benchmark-class-reflection

Conversation

@samsonasik

Copy link
Copy Markdown
Member

@TomasVotruba per your request at:

This PR

  • add benchmark script before vs after ClassReflection refresh
  • update logic to improve performance of Reflection refresh

Here the current comparison:

  • same: refresh with unchanged class content, e.g. a rule visits a class it already changed
  • changed: each refresh toggles an extra constant first, so the content differs every time (worst case for the cache)
same: CPU / call same: memory growth changed: CPU / call changed: memory growth
before #8728 (9939155e2a) 19.3 ms 0.60 MB 19.8 ms 0.60 MB
main (#8728 + #8729, uniqid() key) 20.9 ms 85.1 MB 20.5 ms 89.0 MB
this PR (content hash key) 19.6–20.2 ms 0.60 MB 21.2 ms 11.3 MB

Run on both branches:

php bench/class_reflection_refresh_bench.php
php bench/class_reflection_refresh_bench.php changed

The key is the class content, not spl_object_id(), because rules change the class node in place.

The new ClassReflectionRefreshInPlace test covers it: with an object-id key it loops forever, adding the trait again on every pass.

@samsonasik

Copy link
Copy Markdown
Member Author

@TomasVotruba all green and performance improved from latest patch

Before #8728 in changed mode never rebuilt the reflection (the stale-reflection bug), so compare changed mode against main.

Growth now scales with the number of distinct class versions, not with the number of refreshes 👍

All green 🎉 let's merge 👍

@samsonasik
samsonasik merged commit 53a4d6d into main Oct 20, 2026
49 checks passed
@samsonasik
samsonasik deleted the add-benchmark-class-reflection branch October 20, 2026 15:30
@TomasVotruba

Copy link
Copy Markdown
Member

LGTM 👍

Which Drupal test was broken? Can you send me link?
It's weird that none of all other test spotted it

@samsonasik

Copy link
Copy Markdown
Member Author

Here original drupal-rector build that broken

https://github.com/rectorphp/rector-src/actions/runs/39412220242/job/118599891995#step:6:11

I was sent a patch PR there as it was using ClassReflection which was not rebuild after Class Node changed:

The issue with dropping guard can be even more without the patch, this is what I found right now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants