You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Performance issue when stepping through a deep callstack #760
This seems to be generating the full backtrace through rb_make_backtrace, just to then take the size. rb_make_backtrace (source) generates an array of strings each time it's called. Those strings end up not being used, and after a couple of iterations, you end up with a big memory footprint, which causes the GC to collect them, significantly slowing down the debugger.
Luckily, it looks like you are already aware that this is inefficient (given the // TODO: more efficient API) :)
Looking into alternatives, I came up with a couple of options (but open to any other ideas):
Use rb_threadptr_backtrace_object to skip the formatting of the backtrace, saving some extra memory (but still generating more than necessary)
Both of them, though, require the inclusion of *_core.h, which is not currently possible (debase solves it by using its own version of ruby_core_source)
Yeah this issue makes stepping and finishing quite slow for large callstacks.
I think those ^ PRs should help quite a bit, with both changes together I measured a ~99% improvement in next performance #743 (comment) for an example case. Similar improvement for our internal use case in a large rails monolith.
However one thing to note is that the optimization in #746 won't be applicable for ruby 2.7, as rb_profile_frames will skip C frames for ruby < 3.0 so I don't think we can use it for all versions.
Unfortunately, #473 doesn't seem to have a significant impact in the examples I've tried. It does reduce time/memory consumption, but if the callstack is mostly small methods (so the ration of :return to :line high), it doesn't make a difference.
Given that #746 is for ruby > 3.0, we can't take advantage of it, either.
edit: That being said, even if it doesn't make a big impact in the cases I've tried, I think these optimizations are great and DO cut down on a lot of unnecessary work :)
Activity
st0012 commentedon Sep 22, 2022
FYI, I think @WillHalto is already addressing this in #743 and #746
WillHalto commentedon Sep 23, 2022
Yeah this issue makes stepping and
finishing quite slow for large callstacks.I think those ^ PRs should help quite a bit, with both changes together I measured a ~99% improvement in
nextperformance #743 (comment) for an example case. Similar improvement for our internal use case in a large rails monolith.However one thing to note is that the optimization in #746 won't be applicable for ruby 2.7, as
rb_profile_frameswill skip C frames for ruby < 3.0 so I don't think we can use it for all versions.marianosimone commentedon Sep 23, 2022
Unfortunately, #473 doesn't seem to have a significant impact in the examples I've tried. It does reduce time/memory consumption, but if the callstack is mostly small methods (so the ration of
:returnto:linehigh), it doesn't make a difference.Given that #746 is for ruby > 3.0, we can't take advantage of it, either.
edit: That being said, even if it doesn't make a big impact in the cases I've tried, I think these optimizations are great and DO cut down on a lot of unnecessary work :)
WillHalto commentedon Sep 26, 2022
Gotcha, yeah #743 makes the most difference when the ratio of :line to :return is flipped.