-
-
Notifications
You must be signed in to change notification settings - Fork 119
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Optimize the TracePoint callback #24
Conversation
Actually, I tested with It's now fast enough that the test complete more or less as fast as before Zeitwerk. |
Absolutely, computing the hash code is expensive if called too much, so better short-circuit whatever we can, specially if the test is cheap. What do you think about testing Why does the patch rewrite |
Oops. That a leftover from the previous patch version I'll fix that in a sec and answer your questions |
Good! break unless event.self.name is equivalent, and avoids the extra |
So that is what I was doing in the first patch version. However it didn't make much difference performance wise. Turns out I'm currently digging in MRI to see why exactly, however I have a few intuitions as why. That being said we can probably combine both patches. First discard |
Sounds good! |
Ok, so here's why First it instantiate a new sting every time (already knew that): https://github.com/ruby/ruby/blob/28f619e301cf5f266f38fe764c4018b7fabc77cb/variable.c#L242-L250 Not the end of the world, but it means we definitely want to hold onto that name otherwise we'll generate lots of useless allocations. Then Basically the And if not found it's going to find it the hard way: https://github.com/ruby/ruby/blob/28f619e301cf5f266f38fe764c4018b7fabc77cb/variable.c#L151-L183 That probably explain why it's extra expensive for nameless |
@fxn I updated the patch again. |
Just a couple of minor details:
would be
On the other hand, I think I'd prefer |
@fxn fixed both! |
🙌 |
Thanks for the fast merge ❤️ |
Wait. I'm getting some:
now, not sure what's going on |
Nevermind, I bet the test suite just never encounter these cases. I'll submit a second PR with two new test cases. |
I have just published 1.4.0. It's late here, I'll adapt the Rails integration soon. |
Context
While experimenting with Zeitwerk on an existing Rails app, one test became extremely slow (I'm not even sure how long it takes as it never completed, but I estimate it at over 15 minutes, from ~3s previously).
So I decided to profile that test (or rather a subset of what it's doing) and got this:
So basically what is happening is that the Stripe gem (but could be any other dependency really, I'm not particularly pointing fingers here) is defining methods on instances, which lazily creates singleton classes.
These singleton classes are spamming the TracePoint callback so much that everything slows down to a crawl.
The patch
I tried making the callback bail out as soon as possible when it's clear the class is not relevant to Zeitwerk (i.e. is a
singleton_class
).Unfortunately it's still way too slow, so I'll have to figure something else, but I suppose an optimization is always good to take.
@fxn what do you think? Also if you have other ideas how to solve this issue I'm all ears.
cc @rafaelfranca @Edouard-chin