DEV Community

Cover image for Make it work, make it right, make it fast
Hayati
Hayati

Posted on Originally published at hayatibis.dev

Make it work, make it right, make it fast

Originally published on hayatibis.dev, where the figures move and the toys are interactive.

This line has stuck in a corner of my mind for years. I used to read a lot of Medium posts and books like that, and I’ve shared this order with plenty of people since. When I asked myself where I’d picked it up and when it became a habit, I dug a little deeper and found it credited to Kent Beck. It’s actually older. Stephen Johnson and Brian Kernighan wrote it in Byte in 1983, about C: “the strategy is definitely: first make it work, then make it right, and, finally, make it fast.”

People quote it as three things to do. I read it as an order, where each step has its own definition of done and makes the next one safe.

Fig. 1 · Three gates, each with its own 'done'. Fast is a loop of measuring. The shortcut from working code straight to fast code is the one to avoid.

Fig. 1 · Three gates, each with its own 'done'. Fast is a loop of measuring. The shortcut from working code straight to fast code is the one to avoid. (interactive version)

Make it work

Done means the tests for the behaviour you need are passing. It doesn’t have to be pretty, and it certainly doesn’t have to be fast. It has to be correct, and provably so, because the next step depends on those tests.

Make it right

Now you clean up, and the tests stay green while you do. That is refactoring in the strict sense from principle 01: new structure, same behaviour.

The C2 wiki has a long argument about what “right” means. Some say clean design, others say the edge cases handled properly. I think it’s both: the special cases covered, and code you’d be happy to change next month.

Make it fast

Two people who earned the right to say it have already warned us about this step.

Donald Knuth, in 1974: “We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%.” The second sentence usually gets left out. Knuth wasn’t against optimizing. He was against guessing where to optimize.

Rob Pike, in 1989: “You can’t tell where a program is going to spend its time. Bottlenecks occur in surprising places, so don’t try to second guess and put in a speed hack until you’ve proven that’s where the bottleneck is.” His next rule is a single word: “Measure.”

Try it yourself:

Fig. 2 · An illustrative profile, not a real measurement. The shape is the point: one part overwhelms the rest, and it's rarely the one people bet on.

Fig. 2 · An illustrative profile, not a real measurement. The shape is the point: one part overwhelms the rest, and it's rarely the one people bet on. (interactive version)

Once you have a measurement, “fast” becomes a loop: change the hot part, measure again, stop when you hit the target. That last bit matters. Without a target, you never know when you’re done.

Why the order matters

Fast before right is the expensive mistake. Clever tricks stuck onto messy code get tangled up with it, and the next change has to fight both. Right before work has its own cost: you end up polishing code that doesn’t do the job yet.

I went looking for who first said these three steps and ended up with two people writing about C in 1983. More than forty years on, the languages have changed and agents write a lot of the code, but the order hasn’t. When did you last make something fast, and had you measured first?


Stands on

A new essay every Sunday: get it by email. If you'd like more of these, you can support the writing on Patreon, or buy me a coffee once.

Top comments (0)