Every now and then, I find quotes against optimization, just like this:
The First Rule of Program Optimization. Don't do it. The Second Rule of Program Optimization. For experts only Don't do it yet. --Michael J
-nixCraft (@nixcraft) April 18, 2015
This is quite surprising, since in many cases the speed of a program is fundamental for its success. A UI (or a website) cannot be slow or become unresponsive in some situation. Managing a huge amount of data in few seconds instead of minutes can make the difference from a top seller to an unwanted app.
[A similar reasoning may applies to RAM or disk space too, but in this post I'll be more focused on the execution time.]
The only quote I totally agree with is
premature optimization is the root of all evil.
- Donald Knuth
The explanation is just few rows below.
(At this link you can download the paper)
[A good programmer] will be wise to look carefully at the critical code; but only after that code has been identified.
Identify The Critical Code
It's not always easy to understand where bottlenecks are. A developer with enough experience may imagine which part of the code needs to be optimized but:
- he cannot be sure (scientifically speaking), and
- he needs to have a measure of the improvements.
For this reason, you need to measure the length of (almost) every operation, paying attention to feed the application with a realistic set of data. Another good practice is to collect many samples for every dataset and calculate the average, in order to remove the noise produced by other processes running on the same environment.
After having analyzed the results, you can start to make changes on the parts that last longer, possibly one at time. And then, measure again. Was your modification faster? Good job! Go on with another part. Was it slower? Try another solution.
Now you may want to know which tool to use to take the measurements. There are many performance analyzers out there, but I prefer to collect timestamps from the right places.
There are three reasons behind this choice:
- I have to review the code and this is important because I'll have the structure in mind when I start to make changes;
- some profilers are not very accurate (for example, they return an estimation about which functions take the most execution time, but cannot tell you if this is because they have been called a million times);
- I have a great control over the measured code so, once identified a slow function, I can set more timestamps.
How Much Should I Optimize?
Even if it seems a silly question, there are many different levels of optimization. But the most important thing to consider is that the compiler usually has its own strategies to compile and optimize our code. For this reason, what seems a great improvement, once compiled may not lead to any difference. This is why it's a good idea to compile turning on optimizations.
In addition, please consider code readability, otherwise there is the risk that in the future another developer will get rid of your efforts just because it's too hard to understand. If this kind of optimization is really needed, use comments to explain it why you wrote such an obscure code.
Believe it or not, once this happened to me too: there was a really complicated block of code (with no comments explaining it) that I substituted with few lines of code, just to roll back the change once seen the execution time.