Optimize Late, Benchmark Early

When should you start optimizing your system? There are different opinions: Some think you should finish the implementation of all important features before starting the process of tuning. Others mean that this is way too late and instead advocate early optimizations, arguing that it’ll reduce the risk of substantial rewrites later on.

I recommend doing optimizations as late as possible. The reason is that project requirements always change – a fact which seems to be a law of nature – and an optimized system is usually harder to change. Leaving the tuning tasks for later also minimizes the risk of wasting time on insignificant optimizations, that matters little to the performance of the final system.

But dealing with optimizations later does not mean you can ignore performance completely. Remember, failing fast is an important principle of software development, so you want to discover critical performance issues as early as possible. You should therefore monitor performance, starting as early as possible, by creating test cases that provide benchmarks as the system develops. Not only will that give you a feeling of the overall performance of the system, it will also help you measure the effects of your optimizations – when that time comes.

For me, I use the architecture to draw ‘lines’ in the system, partitioning it into lots of smaller pieces. When I build the initial version, I tend towards overly simple implementations for all of the pieces.

In later iterations — depending on need — I usually start upgrading the models, algorithms or interfaces to accommodate more efficient or expanded versions of the components. I don’t like to go straight into the optimized version mostly because I often don’t fully understand the problem domain until I’ve seen the code run in a real environment for a while. If I am wrong in my initial understanding, optimizing wastes a lot of valuable time.

Typically, in the early years that generally leaves parts of the system as being very crude, while other parts have been significantly enhanced. That’s ok, and not a bad way of dealing with limited time. It all depends on the external factors in the project; politics frequently overrides technical requirements.

The only time I’ll optimize early is when the implementation is so slow that it bothers me while I’m testing or debugging. In other words, when it is blatantly obvious that it will be a problem.

Optimizations have a habit of making code more complicated. Optimizing feature A might take one hour and add 30 minutes to the time to implement feature B later, so its better to implement feature B before optimizing feature A. Also, it is better to never optimize feature A if you can get away with it (thus benchmark before optimize.)