5 ms·
Speed of iteration beats quality of iteration. You can step through the program, reason about what's going on, tracking values as they change. But if you misse
by Androider 5y ago
Speed of iteration beats quality of iteration.
You can step through the program, reason about what's going on, tracking values as they change. But if you missed the moment, you have start again from the beginning (time traveling debuggers being rare). Or maybe you're looking at the wrong part entirely at this stage, and just wasting time.
With print debugging you write a bit of code to test a hypothesis. Then you run it, and you keep running it, and especially if it's an UI program you play with the UI and see how the values change during that run. Ideally the loop to change the code -> see the result should be a few seconds.
You can then git commit or stash your prints, switch branches and compare behavior with the same changes applied. And at the end of the day if you walk away, your prints will still be there the next morning. The debugger doesn't produce any comparable tangible artifacts.
Once you do know where the problem is, and if it's not apparent what the problem is (most problems are pretty trivial once located), that's IMO the time to break out the debugger and slowly step through it. But the vast majority of problems are faster to solve through rapid iterative exploration with prints in my experience (C, C++ for over a decade, Python, now JS/TS).
- damagednoob 5y ago> Speed of iteration beats quality of iteration. That's especially true if you're doing some form of TDD/unit testing. With IntelliJ, I can easily set it to watch for changes and cycle one unit test while I make changes. If something weird happens I can just drop a printf in there, understand and rectify the issue, then take it out. Much faster than step through debugging.
- Shikadi 5y agoGood for simple stuff, but if you find yourself changing your print statements over and over, a breakpoint probably would have been faster
- matsemann 5y agoI often use prints to find the suspect, and then debugger to weed it out. Conditional breakpoints make it easy to stop at the correct place. About your debugging from the beginning: with Intellij on the jvm one can "drop frame", which is basically to discard the current function and start over with the stack as it was. Since I mostly write kotlin my objects are immutable, so rerunning most stuff actually works fine. And hot-swapping the function while the debugger is paused I can even try multiple implementations without having to rerun everything, just drop frame, hot swap, step into the new and updated function. I'd say knowing the debugger well and using it is a faster way to iterate than not.
- Blumfid 5y agoJava debugger can easily drop frames which helps tremendously in going over a function multiple times. Hot code replacement, which I have already and still use since 2005 works very well as well. In php, debugger are half as good but code replacement works immediately. I would rarely use print debugging and in Java never.
- kapep 5y ago> Speed of iteration beats quality of iteration. I totally agree but for me that means using a debugger and make full use of its features. > But if you missed the moment, you have start again from the beginning As already mentioned in another comment, "drop frame" is a standard Java debugger feature. You can easily go back to the start of any method and go though everything again (side effects of already executed code can give some trouble though). > Or maybe you're looking at the wrong part entirely at this stage, and just wasting time. You have the same issue when printing in the wrong parts. Of course you can plaster the code with lots of print statements to see which gets executed. But you can do the same with breakpoints and see where the debugger stops. > With print debugging you write a bit of code to test a hypothesis. Then you run it, and you keep running it, and especially if it's an UI program you play with the UI and see how the values change during that run. I really like conditional breakpoints for this. You write a condition for a state that interests you. Then play around in the UI until it stops for that condition and you can easily inspect the complete state at that moment. This is quite useful for debugging methods that are executed very often. Trigger breakpoint (which disable all other breakpoints until they are triggered) are also useful in those situations without requiring any code. > Once you do know where the problem is, and if it's not apparent what the problem is (most problems are pretty trivial once located), that's IMO the time to break out the debugger and slowly step through it. But the vast majority of problems are faster to solve through rapid iterative exploration with prints in my experience [...] I can just say that I usually locate issued way faster with a debugger. "rapid iterative exploration" could also kind of describe my workflow using breakpoints. Maybe it actually less about the tool and more about your approach for locating issues in the code.
- forrestthewoods 5y ago> Speed of iteration beats quality of iteration. Right. That’s why printf debugging sucks. If you’re in a compiled language with a 2-minute iteration it can take an hour to do a binary search to track down an issue that would take 5 minutes with a proper step debugger. Print debugging is great because it works and is the ultimate fallback. But it sucks and I hate when I am forced to use it.