Premature Optimization is evil
As a software developer, you probably heard someone say “I made this piece of code, it’s optimized”. At first sight, it seems like a good thing. However, it is (most of the time) completely useless and event worse, and will just slow down development.
Premature optimization is the root of all evil in programming - Tony Hoare
What is performance?
2 types of performance
There are 2 types of performance:
- Macro performance: performance at a design level
- Micro performance: performance at a method level
When we speek about premature optimization, we speak about micro performance.
Performance is under a paradigm
As shown by the next figure, there are 3 paradigms in software development:
- Performance: how fast the code can be
- Velocity: how fast the development can go
- Adaptability: how well the code can respond to changes
Velocity: if we only target volocity, there is a high probability the code will have technical debt, something we, as developers, absolutely hate.
Adaptability: if we only target adaptability, we lost velocity and we also end up with premature optimization. Management won’t let us go this way.
Performance: if we only target performance, we lost a lot of velocity and adaptability, resulting with technical debt and premature optimization.
What is premature optimization?
As Sahand Saba said:
Optimizing before you have enough information to make educated conclusions about where and how to do the optimization.
The key word here is premature. It’s different from basic optimization.
Why premature optimization is the root of all evil?
Understanding by life examples
Let’s start with an example:
You have a mobile application based on users. Premature optimization will be to directly scale to hundreds of millions of users, before having acquired even a single one.
Result: you probably won’t have any users and you spent a lot of time optimizing your application for billion of users.
Another example with code:
public class LoginFromMyaTokenServiceFactory implements ISimpsonServiceFactory<...> {
private static final LoginFromMyaTokenServiceFactory INSTANCE = new LoginFromMyaTokenServiceFactory();
private LoginFromMyaTokenServiceFactory() { super(); }
public static LoginFromMyaTokenServiceFactory instance() { return INSTANCE; }
@Override
public ISimpsonService<...> create(ServiceFactoryParameters p) {
LoginFromMyaTokenService loginFromMyaTokenService = new
LoginFromMyaTokenService(p.getMarketCode(), p.getSimpsonCode(), p.getRequest());
return loginFromMyaTokenService;
}
}
This class uses Factory design pattern coupled with Singleton design pattern. I’m not here to speak about SOLID principle, however, 10 years after this code was created, it only create a single object…
Result: There is only cost and no benefit. It makes the code less readable!
Last example:
You’re using some Object language like C#, and you want to write this line:
var myList = new List<int>();
foreach (var element in myList)
{
// doSomething
}
Someone will show up in the code review process, and ask to change the List to a HastSet, because “it’s more optimized”.
Result: you spend 2 hours testing if the List is more efficient than the HastSet and have to argue with your teammate about it. Finally, you find out the HashSet is slower, not to mention the method where you use your list only contains 10 or 20 elements in it. Another waste of time.
As Donald Knuth said:
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%
It means 97% of the time, we should not care about optimization.
The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times.
It’s pretty much all about YAGNI principle.
Suming up premature optimization dangers
- Wasted resources: spending time, effort, and money doing something that turns out to be entirely unnecessary
- Increased mistakes: making decisions based on insufficient information
- Worse outcomes: making even worse code somewhere else because you absolutely want to get advantage of your primature optimization
- Negative emotions: becoming frustrated because of all your irrelevant hard work
How to avoid premature optimization?
Consider asking you the following questions before starting optimizing:
- Why do I need to optimize this piece of code?
- What are the benefits and the costs of this optimization?
- What could I do instead?
- (For a code reviewer) Am I sure to ask for this change? Will it drastically improve application performance?
Not all optimization is premature, so rather than always avoiding optimizing, you need to determine whether optimizations are worth or not.
If you still need performance
In the 3% case, you‘ll actually need optimization. When determining whether you should optimize something, a useful concept to consider is the 80/20 rule (also known as the Pareto Principle). It means that 80% of the positive outcomes that you experience will come from 20% of the work that you do.
The process to resolve a performance issue is the following:
- Have a real performance issue
- Measure
- Try something and measure
- Look for data structures
- Look for SQL queries - Use a profiler that will point out the most costly functions, and measure
- Analyse deeper, find the bottleneck and check for memory, and then measure
Typicall cases when you have performance issues
- You have too many SQL queries: you think you retrieve a collection of users wheareas in reality all the database is returned because there is no lazy loading in the config files
- You want to retrieve and display all the users in one page within one query (use pagination)
- You’re using an array instead of a LinkedList to do lots of insertion and few reading values
- You’re doing a recursive algorithm to calculate some result but you’re not using dynamic programming to help your computer memory be faster
- You want to check if a user exists in a large database. You can use a bloom filter to tackle this problem.
If you want more information, you can check this youtube video that inspire this article: