When it comes to writing high performance software there are different approaches we can take. These different paths, match with how important performance is considered to be.
The first does not consider performance as anything important, the program is written without any attention towards how it performs. Only after users start complaining about the performance, actions are taken to fix it. Users will only complain if it is a killer for them, it isn’t tolerable and thus should be considered a bug.
Another way could be to write software the same as before, but checking the performance from time to time. When the performance of the software falls below some level, action must be taken. This prevents users from complaining, as the performance is boosted before it becomes critical.
A final way is that performance is taken into account when writing software, and is part of the design. This means constant monitoring of the performance, evaluating the choices that are made and making sure it stays above the required level. This level of performance that is desired is often higher than in the previous case.
But what are the consequences of each of these approaches? Is there a single best way to tackle performance?
The first aspect you have to consider is the required time to write the software. It is clear that taking performance into account during the design will take more time to write the initial version, whereas just writing it and not checking for performance is the easiest and fastest way. This is often considered as the most important, as a lot of stress is putting on developing new features, selling them and fast growth. The downside is that if the performance does indeed become a problem, action has to be taken fast to improve it or users may consider switching over to a competitor.
Another aspect that thus should be taken into account is the cost of correcting the performance problems. If performance is taken into account during designer, there should be no cost afterwards anymore. If the performance is monitored, corrective action can be taken sooner, more time can be spend in investigating the problem and finding solutions. If the customer however complains, there is no time left to waste, and performance has to be improved immediately. This means that for some time no new features can be developed and everything is being focused on performance. This counteracts on what the initial idea was, getting as many new features out as soon as possible.
While the performance can still be improved rapidly, and it may seem as an interesting choice as the performance is not a constant burden to think of, there is one other thing to take into account. What type of actions are taken to improve performance and how long they last. If the customers complain, you can only do superficial improvements, as an expensive investigation would take too much time. This mostly comes down to removing obsolete I/O, introducing or increasing a memory cache and re-ordering some statements to prevents code being executed that is not used. With the monitoring a deeper analysis can be done, and better solutions can be found. On top of there there may even already be a clear indication why performance got worse in the first place. If performance is taken into account during the design, the entire design and algorithms are optimized for performance.
The biggest problem with fixing performance when it is too late, is that the solutions don’t tackle the real problem. They may suffice for a short amount of time, but if the users start increasing usage it will become clear that is was not enough. At some point you run out of these superficial solutions, and the real problems begin. Because there is no time to do an investigation, and big rework of the code, but at the same time you have to.
As a final thought I still remember two quotes from my time at university:
First do it, then do it right, then do it fast.
This means that we should not care about performance until later. Only after we have the code working, and it is good code, only then we will look at performance. Though this seems to point into the direction of the first case, where we only fix it when users complain, I don’t believe this is what is meant here. Mostly because it clearly states that we should make it fast, it is part of the process, and not something that should only be done if users complain. At the same time there is a different quote:
Nothing can fix a dumb algorithm.
Which means that finding a good algorithm is important, and as mentioned before you will run out of improvements for the current implementation and algorithm. If that happens and performance is still not good enough, your only option is to change the implementation drastically, or even choose a new algorithm. Because in the end, it doesn’t matter how hard you try to optimize your implementation of the algorithm, if it is a bad and slow algorithm, nothing can make it fast.
So when should performance be taken into account? It will depend on the type of software you are writing. In what way will it be used? Should it be able to handle a lot of load? There is no point in spending a lot of time on finding the best algorithm if a quick implementation would suffice. But this is not always possible to predict up front, so what then? Make the cost nevertheless, and hope it has not been for nothing? In general the best approach to me seems to be just as in the first quote. Make sure you have a working implementation first. After that the code should be cleaned up, as this opens the path for future extensions and modifications, of which performance improvements is one. In the end it may be required to change the algorithm, but if the code was written in a clean way, there should be no reason why this would cause a lot of fuss.