If I had more time I would have written less code

In a a blatant rip-off of the T.S Eliot quote: “if I had more time, I would have written a shorter letter” I had a thought the other day, perhaps:

If I had more time, I would have written less code

It seems to me the more time time I spend on a problem, the less code I usually end up with; I’ll refactor and usually find a more elegant design – resulting in less code and a better solution. This is at the heart of the programmer’s instinct that good code takes longer to write than crap. But as Uncle Bob tells us:

The only way to go fast is to go well

How then do we square this contradiction? The way to go fast is to go well; but if I sacrifice quality I can go faster – so I’m able to rush crap out quickly.

What makes us rush?

First off – why do developers try to rush through work? It’s the same old story that I’m sure we’ve all heard a million times:

  • There’s an immovable deadline: advertising has already been bought; or some external event – could be Y2K or a big sports event
  • We need to recognise the revenue for this change in this quarter so we make our numbers
  • Somebody, somewhere has promised this and doesn’t want to lose face by admitting they were wrong – so the dev team get to bend so those who over committed don’t look foolish

What happens when we rush?

The most common form of rushing is to skip refactoring. The diabolical manager looks at the Red, Green, Refactor cycle and can see a 33% improvement if those pesky developers will just stop their meddlesome refactoring.

Of course, it doesn’t take a diabolical manager – developers will sometimes skip refactoring in the name of getting something functional out the door quicker.

It’s ok though, we’ll come back and fix this in phase 2

How many times have we heard this shit? Why do we still believe it? Seriously, I think my epitaph should be “Now working on phase 2”.

Another common mistake is to dive straight in to writing code. When you’re growing your software guided by tests, this probably isn’t the end of the world as a good design should emerge. But sometimes 5 minutes thought before you dive in can save you hours of headache later.

And finally, the most egregious rush I’ve ever seen is attempting to start development from “high level requirements”. As the “inconsequential little details” are added in, the requirements look completely different. And all that work spent getting a “head start” is now completely wasted. You now either bin it and do-over, or waste more precious time re-working something you should never have written in the first place.

Does rushing work?

This is the heart of the contradiction – it feels like it does. That’s the reason we do it, isn’t it? When compelled by the customer to finish quicker, we rush – we cut corners to try and get things done quicker.

It feels like I’m going quicker when I cut corners. If only it wasn’t for all those unexpected delays that wasted my time then I would have been finished quicker. Its not my fault those delays cropped up – I couldn’t have predicted that.

It’s the product manager’s fault for not making the requirements clear

It’s the architect’s fault for not telling me about the new guidelines

Its just unlucky that a couple of bugs QA found were really hard to fix

When you cut corners, you pay for it later. Time not spent discussing the requirements in detail leads to misunderstandings; if you don’t spot it later on, you might have to wait until the show and tell for the customer to spot it – now you’ve wasted loads of time. Time not spent thinking about the design can lead to you going down an architectural blind alley that causes loads of rework. Finally time not spent refactoring leaves you with a pile of crap that will be harder to change when you start work on the next story, or even have to make changes for this one. Of course, you couldn’t have seen these problems coming – you did your best, these things crop up in software don’t they?

But what if you hadn’t rushed? What if rather than diving in, you’d spent another 15 minutes discussing the requirements in detail with the customer? You might have realised earlier that you had it all wrong and completely misunderstood what she wanted. What if you spent 30 minutes round a whiteboard with a colleague discussing the design? Maybe he would have pointed out the flaws in your ideas before you started coding. Finally, what if you’d spent a bit more time refactoring? That spaghetti mess you’re going to swear about next week and spend days trying to unravel will still be fresh in your mind and easier to untangle. For the sake of an hour’s work you could save yourself days.

How much is enough?

Of course, it’s all very well to say we will not write crap any more; but it’s not a binary distinction, is it? There’s a sliding scale from highly polished only-really-suitable-for-academics perfection; to sheer, unmitigated, what-were-you-thinking-you-brain-dead-fuck crapitude.

If spending more time discussing requirements could save time later, why not spend years going through a detailed requirements gathering exercise? If spending more time thinking before coding could save time later, why not design the whole thing down to the finest detail before any coding is done? Finally if refactoring mercilessly will save time, why not spend time refactoring everything to be as simple as possible? Actually, wait, this last one probably is a good idea.

Professional software development is always a balancing act. It’s a judgement call to know how much time is enough.

How long does it take?

When working through a development task I choose to expend a certain amount extra effort over and above how long it takes me to type in the code and test it; this extra time is spent discussing requirements, arguing about the design, refactoring the code etc etc. Ideally I want to expend just enough effort to get the job done as quickly as possible (the lazy and impatient developer). If I expend too little effort I risk being delayed later by unnecessary rework; if I expend too much effort I’ve wasted my time.

However, I don’t know in advance what that optimum amount of effort is – it’s a guess based on experience. But I expect the amount of effort I put in to be within some range of the optimum – the lowest the point on the graph:

All other things being equal, I’d expect the amount of time it actually takes to complete the task to be within some margin based on how close I got to the optimum amount of effort. Sometimes I do too little and waste time with rework. Other times I spend too long – e.g. too much detail in the design that didn’t add any value – so the extra time I spent is wasted.

This is by no means all the uncertainty in an estimate; but this is the difference between me not doing quite enough and having to pay for it later (refactoring, debugging or plain rework); versus doing just enough at every stage so that no effort is wasted and there’s no rework I could have avoided more cheaply. In reality the time taken is likely to be somewhere in the middle: not to great but not too shabby.

There’s an interesting exercise here to consider the impact experience has on this. When I was first starting out I’d jump straight into coding; my effort range would be to the left of the graph: I’d spend most of my time re-writing what I’d done so the actual time taken would be huge. Similarly, as I became more experienced I’d spend ages clarifying requirements, writing detailed designs and refactoring until the code was perfect; now my effort range would be to the right of the graph – I’d expend considerable upfront effort, much of which was unnecessary. Now, I’d like to think, I’m a bit more balanced and try to do just enough. I have no idea how you could measure this, though.

Reducing effort to save time

What happens when we rush? I think when we try to finish tasks quicker, we cut down on the extra effort – we’re more likely to accept requirements as-is than challenge them; we’re more likely to settle for the first design idea we think of; we’re more likely to leave the code poorly refactored. This pulls the effort range on the graph to the left.

To try and get done more quickly, I’ve reduced the amount of effort by “shooting low”: I cut corners and expend less effort than I would have done otherwise.

The trouble is this doesn’t make the best-case any better – I might still get the amount of effort bang on and spend the minimum amount of time possible on this task. However because I’m shooting low, there’s a danger now I spend far too little extra effort – the result is I spend even longer: I have to revisit requirements late in the day; make sweeping design changes to existing code; or waste time debugging or refactoring poorly written code.

This is a classic symptom of a team rushing through work: simple mistakes are made that, in hindsight, are obvious – but because we skipped discussing requirements or skipped discussing the design we never noticed them.

When I reduce the amount of extra effort I put in, rather than getting things done quicker, rushing may actually increase the time taken. This is the counter-intuitive world we live in – where aggressive deadlines may actually make things go more slowly. Perhaps instead I should have called this article:

If I had more time I would have been done quicker

23 thoughts on “If I had more time I would have written less code

  1. Philip Schwarz

    Hi, interesting post.

    After reading it I went beck to Martin Fowler’s excellent The Design Stamina Hypothesis. Design-wise, I wonder how your ‘optimal amount of effort’ relates to the design stamina of the project? Is the optimal amount of design effort the amount that gives you the greatest stamina, i.e. allows the project to go as fast as possible for the longest amount of time?

    1. Thanks for the link, Philip – hadn’t seen that before. Interesting stuff. Definitely seems like a similar idea.

      I’d definitely agree with Martin’s idea that the line is much lower than people think – certainly weeks, if not days in some cases. I think that’s the real challenge in balancing the effort you spend – you need to put in more than you think or you incur the cost sooner than you think.

      Good stuff. Thanks for the link!

    1. Thanks! Glad you liked it. And absolutely understand on the diagrams, I’d hoped they would help but… in hindsight not sure they make it clearer!

      All I was trying to say is that to complete some given task there’s an optimum amount of effort to spend. In trying to get things done quicker, we put in less effort so the task takes longer. Often, I believe, by putting in more effort – i.e. more talking to people, more up front thought – we’d actually get done quicker overall.

  2. ASDP

    Great Article. Really.

    Just as a nitpicking… not very relevant but well :

    The quotation about long and shorter letters is a misquotation, Eliot himself ripped it from the 17th century philosopher Blaise Pascal who wrote in a letter : “I have made this letter longer than usual, only because I have not had the time to make it shorter. ”
    And Pascal probably ripped it from Cicero.

    As I said, irrelevant nitpicking.

  3. Andrew

    Experience plays a huge role in this as well. I used to have a coach who said “Practice doesn’t make perfect, perfect practice makes perfect” (I’m sure he ripped that off from someone, although I have no idea who). I’m a fairly young developer and I struggled a lot getting out of the gate and made a ton of bad design choices. Luckily for me I work at a place where I’m very rarely rushed, so I have time to go back over my decisions and refactor and improve and learn. If we keep rushing developers they won’t get the experience needed by applying the more elegant and simplistic designs.

    1. That’s a really interesting point – it’s easy to forget that much of the learning in this job is done while delivering; if that delivery is always under pressure there’s no room for mistakes and no chance to experiment and learn.

  4. Steve

    Thanks for the article. I’m not sure that “effort” is clear — do you mean effort towards project organization and team communications, or effort towards Making Stuff Work[tm] (coding). I think it’s the former, but not sure, because wherever you spend your time is “effort”.

    1. Yeah I couldn’t find a good word so used effort as it was the closest I could find. I really mean “energy directed at completing a task” (so the latter, really – although it could equally apply to out-of-band stuff like organisation, I guess).

      Good programmers are lazy, so will always look to spend the minimum amount of energy possible to complete a task; but sometimes that means we optimise too early – we put in less energy but end up taking longer. Maybe effort was the wrong word – if you can think of a better one let me know!!

  5. another random person

    I don’t really get the graphs. How does it make sense to chart time against effort. in programming Isn’t the best way of measuring effort precisely to measure the time an activity takes. for example, working for two hours takes more effort than working for one hour. I don’t grasp in the charts how effort can actually go down as time increases.

    1. I guess what I’m trying to get at is that effort (or energy expended) is the controllable variable; time is implied by the system.

      So I get to decide whether I do a massive design up front and try and think through every possible case (so expend a great deal of effort, all the way to the right on the graph); or I might decide to do no design, not talk to stakeholders, not plan any testing, not write any unit tests and just hack until it vaguely looks like it might work. That’s probably far to the left on the graph.

      My point is that we get to control the amount of effort or energy we spend in aiming to complete a task, and sometimes doing *more work* will get the task done quicker.

  6. Pingback: » Think More, Code Less Blog, Cutely

  7. Pingback: Read This! « The Short Talk

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.