Saturday, July 7, 2012

Another Optimization

When you finish your project and decide to optimize it, you usually look for that little loop where the processor inevitably spends 80% of the run-time, and find a way to make it faster. If it's much slower than it needs to be, you're likely to go to as far as using a different language for just that part of the code.
This logic should be applied to programmers too, not just processors.
Now, the numbers aren't consistent, but you're almost sure to spend at least 30% of your development time on debugging. Often more. Much, much more. Some people put it as high as 90% even. That's a loop you should really strive to optimize at all costs.
Let's talk about debugging then.

We all get stuck in the compile/debug cycle (AKA edit/compile/test cycle).
The compiler is usually beyond our control (and often fairly quick for minor changes).
The editing depends on a lot, but very often you just want to make many tiny changes and test their effect, or you think you can fix a bug with just one tiny change, so that's pretty quick too.
Then you hit the testing part, where you have to run the program, enter your username and password and maiden name and social security number and shoe size, then you loyally watch the loading screen for several minutes while the computer resets the hardware, initializes the data structures, synchronizes the clocks, refills the shark tank, contacts the server, and... wait, what was I trying to check again?

This is all a waste of time. Fortunately, it's possible to avoid it. Here are some methods to do that:

Debug Mode: I don't mean selecting Debug in that little combo box and then having the privilege of breakpoints, line-by-line debugging, and those few extra log prints that depend on the _DEBUG flag. That's fine for some things, but not many. Instead, you can introduce a new running mode for your application, and use it to allow yourself to do things that no regular users should ever be able to do: 

  • Skip some initialization processes. If the application normally reads a gigantic database from a remote server but all you want to debug is the feature that snaps the toolbar to the left side, no reason to start reading databases.
  • Run things in the wrong order. If you're working on a game and want to iterate on the design of level 2, it's ridiculous to have to run through level 1 each time. It's equally ridiculous to have to run through the first quarter of level 1 just to iterate on the second quarter. 
  • Skip other things. Splash screens, username and password prompts, data verification, confirmation messages, anything that isn't related to what you're doing.
  • "Break" various components in run-time to simulate errors. If you want a truly robust application, you should be able to test a whole array of errors, and making these errors actually happen in the right moment might require a lot of effort.
  • There's nothing inherently wrong with extra log printing when _DEBUG is defined, actually.


Data Injection: Assuming your program does more than calculate a large prime number, there is usually some input involved. Input comes from various sources, and 4 out of 5 times you really don't want to depend on what these sources happen to be doing at the moment.

  • Simulate devices. If your program monitors a nuclear reactor, but your company only has 4 of them and they're all being temporarily used by another team, you better have a Fake Nuclear Reactor Simulation Module or you literally can't work until they're done.
  • Simulate servers. It's fine that you're rewriting the 3D display of a spaceship's position around Neptune, but that's no reason to wait for 5 minutes for the data from the space station every time you want to check that the wings are rendered in just the right shade of magenta. Prepare fake input and a way to read it.
  • Reproduce results and bugs. The guys at QA found out that your cat-tracking software crashes only when the cat chases the laser pointer just so. Instead of convincing the test cat to do the exact same thing dozens of times until you find the memory leak, simply save a recording of the Psychoscopic Feline Monitor data and you'll be able to work on the exact same data sets with zero effort until you locate the problem.
  • Just save time. Yes, of course users have to supply a username and password, and enter a Captcha correctly, and give a urine sample, just to log onto the system. As a developer you may want to log on hundreds of times per day, and even if it only takes you a few seconds, the wasted time accumulates. Besides, who enjoys typing the same thing again and again?
  • Unit tests, but that's pretty obvious.


Debugging UI: There is nothing wrong with investing some time in windows and forms that the end-user will never see. I think the odds are decent that you'll spend more time working on the program than the average user will spend using it, anyway.

  • Watch the unwatchable. There's plenty of reasons why putting a breakpoint in the code just to check the value of a variable is impossible (multithreading being the most obvious one), but there's nothing stopping you from displaying this data somewhere on the screen, in whichever format you want (you hear that, everyone-who-ever-used-a-string-in-C++?).
  • Bypass the "compile" part of the cycle. You just want every component of the GUI to have the perfect color, why should you recompile for every tiny change when you can just have a nice console with sliders and color pickers and such?
  • If you're using the right language, you can simply change the code while running.
  • Change data while running. This allows you to undo changes and reset states without having to re-run the whole thing, or easily simulate specific conditions that are too much effort to create manually like a real user would.

Yes, every one of these ideas is time consuming to some extent. But if your project is going to last more than a few months then the advantages will make up for it pretty quickly. Not to mention that some things you build for one project might then be reused for many other projects over many years. 

There are probably many other tips and tricks out there, but these are the ones I could think of today. If anyone knows other useful methods, I'd love to hear about it.

No comments:

Post a Comment