One of the hardest parts of software development is knowing what to work on. We all love to write code and build things. Developers are also expensive and in short supply. One of the biggest challenges is making sure we are making good use of our time. The last thing we want is to ship code that our users don’t like or that doesn’t work. How much time we should dedicate to performance tuning and optimization is always a balancing act.
If we don’t do any performance tuning or optimization, our new product launch could be a complete disaster. The launch of HealthCare.gov for the Affordable Care Act is one of the most famous failures in recent times. We also don’t want to waste an enormous amount of time doing performance optimization on things that don’t matter. Many development teams get caught up in focusing on optimizing for performance and scale before they have validated their new product functionality.
Premature optimization is spending a lot of time on something that you may not actually need. “Premature optimization is the root of all evil” is a famous saying among software developers. Its source is credited to Donald Knuth. Here is the full quote from his book The Art of Computer Programming:
“The real problem is that programmers have spent far too much time worrying about efficiency in the wrong places and at the wrong times; premature optimization is the root of all evil (or at least most of it) in programming.”
This original quote about premature optimization was from a book published a very long time ago in the 1960s. That was arguably a different time when mainframes and punch cards were common. CPU processing cycles were also scarce.
Most development teams today are used to shipping code continually and iterating quickly. Most all teams leverage agile methodologies. We know that if there is a bug in our software we can deploy a fix pretty easily to our web server.
The sentiment of premature optimization is still very valid though and the concept applies to modern development. Premature optimization is something that developers should always be thinking about. It is something they should always try to avoid in their daily work. It applies just as much today as it did in the days of mainframes and punch cards.
A classical example of this is a startup that spends an enormous amount of time trying to figure out how to scale their software to handle millions of users. This is a very valid concern to be thinking about, but not necessarily acting upon. Before you worry about handling millions of users, you need to make sure that 100 users even like and want to use your product. Validating user feedback needs to come first.
The best way to explain this is with a simple story. I am currently working on a side project that has to do with content marketing and measuring its performance. It requires collecting data from Google Analytics and manually crawling the pages of a website to create some reporting dashboards.
This project involves collecting potentially a very large amount of data. Crawling web pages is also a time consuming process. If I started selling the product to a lot of clients, these would both be big scalability issues.
My biggest concern right now isn’t performance or scale. I’m spending my time working on prototyping some of the features and designing UI mockups of other parts of the product. I have been focusing on getting user feedback to iterating on the final product features and functionality. I am trying to prevent wasting a lot of time on things that may never be needed.
Instead of focusing on getting the product right, I could have been doing all of these things:
- Evaluating several storage options for all of the Google Analytics data that I need to collect and query which could be “big data”
- How to queue up and scale out a massive number of workers to crawl all the website pages weekly
- Evaluating if I should use a multi-cloud deployment to ensure highest availability
- Figuring out how to architect a product to host in several data centers internationally for when I go global
- Ensuring I have 100% test coverage for all of my code
- Building automated synthetic tests
Not to mention lots of other features that I could build or not build while I’m trying to figure out what my customers want.
None of this stuff matters… yet
Trying to perfect my usage of Docker, Kubernetes, automated testing, or continuous deployment is definitely a waste of time if I’m not shipping it to anyone. “We can ship fast to no one! Yaay!”
You know what matters?
Figuring out if my customers like the features or product I am working on.
I could spend a lot of time working through the items that I listed above. In the future, I will have to figure these out. For now, I am avoiding premature optimization.
Validating product feedback and perfecting the product feature set is an order of magnitude more difficult (and important) than figuring out any type of performance optimization or scaling issues. Identifying the feature set and requirements will also change and dictate optimization decisions.
For my side project I mentioned above, if I decide that my target customer is startups versus large brands, how much data I need collect and the feature set could change dramatically. I would argue that the concept of premature optimization relates to more than just literal performance optimization concerns. It also relates to where we focus our time and energy.
We always need to focus our efforts on the right problems to solve. We need to avoid building things we aren’t going to use. Focus first on shipping code that you know people will use. You can always improve it.
The more confidence you have that you are building the right things, the more time you should put into proper software architecture, performance, scalability, etc. Striking this balance is always the challenge. Like most things in life, the answer is almost always “it depends”.
The performance and scalability of your application are important. You just need to make sure you are building the right feature set first. Avoid premature optimization by getting user feedback early and often from your users.
If you need help optimizing the performance of your application, be sure to check out our offerings. Prefix can help you find performance problems as you write your code. Retrace will help you find slow code, errors, and much more on your servers in QA and production.
- How to Create SQL Percentile Aggregates and Rollups With Postgresql and t-digest - August 10, 2020
- What Is NullReferenceException? Object reference not set to an instance of an object - March 11, 2020
- C# Exception Handling Best Practices - March 4, 2020
- IIS Error Logs and Other Ways to Find ASP.Net Failed Requests - November 6, 2019
- List of .Net Profilers: 3 Different Types and Why You Need All of Them - October 30, 2019