I recently moved from Malmö, Sweden to London, England. Today I did some major grocery
shopping. When I put my items on the checkout counter, I did what I always do in Sweden - I try to make things as easy as possible for the cashier. You see, in a typical Swedish grocery shop, what slows down the line is the cashier. She/he can’t scan the items fast enough, and so helping him do a faster job helps the line flow more efficiently.
Today I made sure that the EAN-codes were all facing the cashier, and no items were piled on top of each other, trying to make the cashiers job easier. I looked at the people on the other lines, piling stuff without concern on top of each other and felt good that I had cracked the system and would get serviced faster than the rest. Unfortunately, very soon I saw that my cashier was working very slowly. I realized that in England, the cashier will start to put the goods in bags if you don’t, something that a Swedish cashier will never do. Most of her time was now spent packing stuff in bags instead of scanning items. I felt stupid, piled the rest of my stuff on one big heap, and moved over and started packing goods into the plastic bags. Presto, everything was running fast again.
This is exactly what happens in software systems too. A developer, having the best intentions in the world, will optimize his code based on his experience of what will be slow. Measuring of the live system will show that the actual bottleneck is somewhere else, and the optimization was naught.

In the last PDC, Rico Mariani, Performace Architect for the whole Developer Division in Microsoft, stated his ten rules for optimization. They where:
1. Measure
2. Measure
3. Measure
4. Measure
5. Measure
6. Measure
7. Measure
8. Measure
9. Measure
10. Measure
The problem was not that the optimization didn’t help. The problem was that the optimization made the code harder to read. And reading code is very important. When I see weird code, and the defense for it is “it’s faster that way”, I cringe. Most of the time, insignificant performance gain has come from that tweak, but understanding the code has now become more work.
Think of it this way. In a project, you are turning resources and time into runnable software. The time you spend time optimizing code costs you is time you won’t use on other parts of the project. Also, you are taking time away from the other developers of the team, because they will have a harder time understanding your code. The gain from you optimization is neglectible, and the cost is very real.
My suggestion is not that you totally ignore the performance of the system, but that you direct your efforts where it’s needed. Schedule a couple of hours every other iteration or so, and find out, first hand, where the bottlenecks are for the important uses of your system, and then act on that information.
Even if you measure and make sure a component needs optimizing, don’t base the optimizations you use on just the performance improvement you get. You still have to think about readability tradeoffs. Performance improvements are transient effects, and the inevitable changes to the software or hardware stack below your application will likely reduce these improvements. But if you obtain these transient improvements using really unreadable code you will be forever saddled with it because nobody will want to take the trouble to understand it.
Left by Kartik Agaram on November 23rd, 2006
As another point to this, when you need to optimise, it’s usually better to make algorithmic optimisations where possible rather than trying to make lower-level changes to the operation of small pieces. Most often, slowdowns are caused by just using the wrong algorithm or data structures. For example, replacing an association list with a proper finite map implementation using balanced binary trees internally will usually speed things up immensely, and often provide a nicer interface to the functionality that was provided by the association lists, potentially increasing the readability of the code. The same goes for lists which are being used as sets — if you’re not just iterating over it, and instead have to do lots of things like intersections, or large amounts of element testing, you’re better off with a proper set library.
Left by Cale on November 24th, 2006
Kartik:
If the performance of the system is such that it’s not usable, changing the code to become faster, and less readable is ok. But it has to be a decision based on facts, not on guessing.
Cale:
I think you are right. Using an appropiate algorithm on a problem is usually the best way to get decent performance. The main point I’m making is still valid though - if you have to sort a list that will never contain more than 10 items, using a fast, but advanced and hard to read algorithm might be an overkill.
Left by Andres on November 24th, 2006
Hey, those ten optimisation rules sure has some similarities to the ten focus points of Microsoft:
1. Developers
2. Developers
3. Developers
4. Developers
5. Developers
6. Developers
7. Developers
8. Developers
9. Developers
10. Developers
Left by Johannes on November 25th, 2006
You’re absolutely correct that many developers tend to optimize prematurely — and not just the inexperienced developers; sometimes the more experienced developers have built up a big bag of optimization “tricks” that they fill their code with (sometimes more to impress the junior developers than anything else!)… ignoring the fact that they’re making their code far less readable for a negligible performance gain.
But it’s also an awful idea to put performance and resource usage out of your mind completely until basic development is complete and you’re running tests. If you ignore scalability and performance in your basic application design, it’s easy to cook up a design that’s very clear and easy to follow, but will be totally unworkable in your final product; either memory demands will be enormous for even simple uses, or scaling up to thousands of users will be impossible, etc. — and flaws in your core design are much, much harder to correct at that point.
This is where I feel the concept of elegance really comes into play in software design and code. A very simple design can easily result in an extremely inefficient implementation; a design for optimum performance is often painfully complex; a truly elegant design (like elegant code) is easy to understand and avoids arcane tricks, but is also concise and efficient.
This is also where simple research comes into play. To use your checkout counter example — if you’d watched a few other people check out before you built your own plan, you would have understood the general problem before you started. Walking through a general design and making estimations on usage levels, memory requirements, etc. based on performance testing on past projects and research can be invaluable far before you have any code you can test.
Left by Rob Whelan on November 26th, 2006
Measure early and often (automate)
Left by Lloyd Budd on November 27th, 2006
Everyone always says this is a trade off (readability-optimization), but I don’t agree. Most production code can be redesigned to be both more readable and faster. Poor optimization will make code less readable, but can also make it slower.
Rico Mariani’s top ten list is clever, but I wouldn’t use Microsoft as my standard for optimization - almost every product they have is ridiculously slow.
Developers SHOULD write code trying to make everything run fast. As long as you ignore trivialities (i.e. code with fewer comments compiles 0.0001% faster) and know how to optimize (some understanding of how the compiler, OS, and hardware work) there are very few trade offs between readability and optimization. And telling the developers to favor readability over optimization solves these.
There is a very real trade off between developer time spent writing code and optimization. Developers understand which is appropriate, so this isn’t a problem.
Left by Brad Bellomo on November 27th, 2006
Il problema delle ottimizzazioni premature…
…
Left by AntonioGanci on November 29th, 2006
As Brad almost writes, I think there is (atleast?) an important third factor, which is developer time or initial investment cost, if you prefer. You can write optimized and readable code, but it brings a higher initial expense. Which usually is fine, enter other tradeoffs.
Left by mawi on January 6th, 2007