Skip to content

Byebug 11 performance decreases when breakpoint set #558

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

Open
bdeterling opened this issue May 19, 2019 · 3 comments
Open

Byebug 11 performance decreases when breakpoint set #558

bdeterling opened this issue May 19, 2019 · 3 comments

Comments

@bdeterling
Copy link

bdeterling commented May 19, 2019

Problem description

Byebug 11.0.1 slows down code drastically when a breakpoint is set.

Expected behavior

I expect it to slow down the code somewhat - 2x or even 3x.

Actual behavior

It slows down much much more than that.

Steps to reproduce the problem

# test.rb
require 'benchmark'
puts Benchmark.measure {
  big = []
  10000000.times do |i|
    big << rand(36**16).to_s(36)
  end
}

Baseline ruby test:
ruby test.rb
14.670000   0.670000  15.340000 ( 19.430349)

Baseline byebug test (no breakpoints):
byebug test.rb
=> 1: require 'benchmark'
...
(byebug) c
 15.000000   0.210000  15.210000 ( 15.215282)

Byebug test with added breakpoint:
byebug test.rb
=> 1: require 'benchmark'
...
(byebug) b 3
(byebug) c
=> 3:   big = []
   4:   10000000.times do |i|
...
(byebug) c
110.460000   0.590000 111.050000 (111.636692)

So about a 7x slowdown just by setting a breakpoint. If you remove the breakpoint after you hit it, things are fine. So the workaround is to clear your breakpoints before you do the final continue.

I first noticed this in a Rails app, where leaving a breakpoint set after a request causes every other request to run a very long time. I just mention that to show I don't think it's an artifact of this kind of calculation, I think it just slows down any Ruby code by a factor of 7+.

I tested with both Ruby 2.4.4 and 2.5.1. I also tested with byebug going back to 6 and all exhibited the issue. Anecdotally, I've been using byebug for years and just started noticing this problem so it could be related to the newer Ruby versions. I will try to find time to go back and check 2.3 and earlier.

Thanks for looking into this.

@deivid-rodriguez
Copy link
Owner

deivid-rodriguez commented May 26, 2019

Hi @bdeterling.

This is expected. After you run continue, byebug needs to check whether to stop or not for every line run by your program. This has an overhead, unfortunately. If you don't have any breakpoints enabled, there's nothing to check, so byebug optimizes that particular case by disabling itself before letting the program run.

@bdeterling
Copy link
Author

Ok, that does make sense, but just to make sure I wasn't crazy I went all the way back to Ruby 2.0 and byebug 2.0 and found that byebug used to slow the process down by about 4x, but it didn't matter whether a breakpoint was set or not. The current situation is better: <2x slowdown without breakpoints and 7x slowdown with breakpoints versus the old 4x slowdown either way.

Perhaps some day there could be a run to end command that clears breakpoints and then continues. It's not a big deal to type del/y, but it's a pain when you forget. Or maybe a ctrl-something to stop at the current line so you can delete them when you forget.

Thanks for the response.

@stwr667
Copy link

stwr667 commented May 29, 2020

Ok, that does make sense, but just to make sure I wasn't crazy I went all the way back to Ruby 2.0 and byebug 2.0 and found that byebug used to slow the process down by about 4x, but it didn't matter whether a breakpoint was set or not. The current situation is better: <2x slowdown without breakpoints and 7x slowdown with breakpoints versus the old 4x slowdown either way.

That's helpful to know. I've seen this anecdotally, but it's helpful to know someone's confirmed it's the case and got some rough numbers on the difference. Thanks @bdeterling. Before reading this I wasn't sure of the distinction in performance between adding a byebug statement, and manually adding breakpoints during execution.

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

No branches or pull requests

3 participants