Don't make any diagonal moves (ie. make many small changes)

Posted by james on July 25, 2015

Don't make any diagonal moves (ie. make many small changes)

While developing, it's always tempting to combine two changes at once. If you're fixing a bug in your code, and there's also an upgrade to the library you happen to be using, it's tempting to combine the two. "I may as well do both while I'm here, it'll save time."

It's true in a short-sighted sense; there is overhead to making changes, so combining changes will save overhead.

However, similar to products that have total-cost-of-ownership, there's a total-cost-of-dev for changes. This includes testing time, bug fixing time, predictability, reliability, and most imporatntly risk.

Let's assume some very random and meaningless numbers:

Change #1: 2 units of time
Change #2: 3 units of time
Overhead for a changeset: 1 unit of time

So making these changes separately:

Change #1: 2 unit
Overhead: 1 unit

Change #2: 3 unit
Overhead: 1 unit

Total: 7 units

Making the changes together:

Change #1: 2 unit
Change #2: 3 unit
Overhead: 1 unit

Total: 6 units

This saves 1 unit of time. That's good.

However, let's think total cost of dev...

Separate changes:

Change #1: 2 unit
Overhead: 1 unit
Testing time: 1 unit
Bugfix time: 1 unit

Change #2: 3 unit
Overhead: 1 unit
Testing time: 1 unit
Bugfix time: 1 unit

Total: 11 units

And combined changes:

Change #1: 2 unit
Change #2: 3 unit
Overhead: 1 unit
Testing time: 2 unit
Bugfix time: 4 unit

Total: 12 units

The trick here is to assume that 1) combining changes increases the risk of bugs, since the overall changeset is more complicated, and 2) that debugging in this case is more complicated & time consuming than if the changes were separate & smaller.

In the original example, say you make a bugfix, but in testing find that this introduces another unrelated bug. If you've also decided to upgrade the library itself, how do you know if the new bug is from your fix or the upgraded library? If downgrading the library is non-trivial, the debugging gets much more complicated & time consuming.

Even if you ignored the added complexity of debugging, there's also the fact that the amount of time saved (ie. the overhead) is trivial compared to the overall time spent. Saving a few minutes on something predicatable does not seem like a smart choice if it adds complexity and time to the already-unpredictable process of debugging. If anything, we should increase the amount of predictable time (on things like defensive programming & process) to reduce the unpredictable time (ex. spending days fixing issues on Production due to a "very simple fix" like upgrading a library or fixing a small bug).