-
Notifications
You must be signed in to change notification settings - Fork 129
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
Faster next / finish by using rb_profile_frames
#746
Conversation
Basically I agree with the idea but at least on ruby 2.7 and before it doesn't work because it skips C method frames. I need to check more it is same or not on CRuby's code. NOTE:
|
@ko1 Yeah, currently this will only work for ruby 3.0 and up
Is there any modification we could do for ruby <= 2.7? I don't think there would be a way to use Alternatively, perhaps we could restrict the logic so that the |
That sounds good. Maybe that would be a more long term improvement and this optimization could be seen as a short term way to improve the performance.
Is that something we could do now? Would that be a better way to optimize instead of using
Interesting, I am not sure if it would be needed, see the performance improvement in #743 (comment). It seems to work well. It might also be difficult to handle exceptions/conditional logic when setting the breakpoints in this way. |
Correct. |
ae1499e
to
533fef0
Compare
@ko1 What do you think of this: 533fef0?diff=split&w ? If we wanted to use the approach in this PR to make performance fast for ruby >= 3.0 we could do something like that. That will allow use of rb_profile_frames in the ruby >=3.0 and use existing frame_depth implementation in other versions. |
Github actions shows errors on Ruby 3.0? On Ruby 3.2, I'll prepare the new debug feature to get depth directly. |
Yeah, I can work on a fix for the failing versions 👍 |
533fef0
to
55a0115
Compare
|
On ruby < 3.0 rb_profile_frames omits c frames so we cannot use it to get frame_depth. On ruby < 3.2.0 it adds an extra dummy frame in the output that must be accounted for.
55a0115
to
afc15d1
Compare
Done.
@ko1 you can go ahead and merge with squash 👍 |
Description
rb_make_backtrace
in DEBUGGER__.frame_depth, we can improve the performance of frame_depth substantially for common cases. This leads to much fasternext
andfinish
performance.rb_profile_frames
is notably faster thanrb_make_backtrace
as it returns pointers and does not perform allocations (which rb_make_backtrace does).rb_profile_frames
which we have picked here as 4096. This should cover the vast majority of calls. (i.e. the common stack depth in our large codebase is in the hundreds). There is a fallback torb_make_backtrace
to support the very large stack depth cases.rb_profile_frames
and not need the fallback, however there is currently an open issue regarding the "start" parameter not working properly, which would be required for that.Co-authored by: @jhawthorn
Note
Currently, this approach will only work with ruby >= 3.0.
It appears that for ruby < 3.0,
rb_profile_frames
omits c frames. So before moving forward, we would need to modify the logic here to support ruby < 3.0, or just restrict therb_profile_frames
approach to only be used for ruby >= 3.0.Examples/validation
This file simulates a large callstack with deep recursion + method call:
Testing a step over the call on line 13 with this command:
Baseline - no stepping:
Stepping before this change:
Stepping after this change:
next
for the example case.Expand to see the fallback results here
Extreme case: stack depth larger than BUFF_SIZE
We can test this with:
Baseline - no stepping:
Stepping before this change:
Stepping after this change:
^ It gives an ~80% performance improvement for this extreme example, where we hit the rb_make_backtrace fallback.