Premature Optimization: A Serious Problem
Programming May 30th, 2007 - 6,202 viewsIt’s a common problem among programmers. Elegant code becomes obfuscated by a series of hacks and kludges that are supposed to “improve performance.” Two months later when your partner goes back to ajaxify your login form, or implement a bugfix, they lose three days trying to understand 1,500 lines of spaghetti code. Despite the long-term repercussions, many seasoned programmers continue to optimize prematurely with no regard for their partners’ happiness or their own well-being.
Entire books can be (and have been) written about performance, optimization, and scalability. Many programmers become fixated on making a particular piece of code run as quickly as possible on whatever hardware they have at their disposal. But performance gains often come at the expense of the flexibility and maintainability of the system. And in many cases, performance gains are so tiny that they are practically immeasurable. In short, optimization is the target of countless hours of misguided effort by programmers.
Implement, then optimize
Rule number one: don’t worry about optimizing until you’re done implementing and debugging the system. Many programmers iterate over small sections of code, unrolling loops and removing layers of indirection before they’ve completed a piece of functionality. The truth is that software systems typically spend the vast majority of their time in small sections of code, and it’s damned near impossible to predict where those sections will be until you’ve finished coding and have real users on the system. Even then, you often need a profiler to determine what areas to focus on — but I’m getting ahead of myself.
Whenever you have a trade-off between performance and maintainability, choose maintainability. You can always go back and tweak things for performance if necessary. It’s much harder to iterate over code to improve a system’s architecture or maintainability. And, more often than not, you’ll finish a piece functionality and find that it performs just fine.
Scalability trumps performance
It’s usually not a good idea to sacrifice scalability for performance. The uninitiated might need some explanation here — the distinction between scalability and performance is subtle, but very important. A system is scalable if its capacity can be increased while maintaining an acceptable level of performance.
What’s “acceptable” will depend on the application. For a web application we might say that a response time under 250ms is acceptable since that’s about the limit of human perception. For a relational database server that is expected to handle hundreds or thousands of transactions per second, acceptable performance would need to be defined differently.
The important thing to remember is that it’s usually a bad idea to improve performance at the expense of scalability. Or, at the very least, this decision should not be taken lightly. This is particularly true for web applications, and other centralized components that may experience increased usage over time. But even single-user desktop application experience scalability problems. Just try manipulating an image in Photoshop that doesn’t fit in RAM and you’ll understand what I’m talking about.
Profile, profile, profile
If performance does become an issue, don’t assume you know what the problem is — you’ll probably be wrong. If your web app is spending 5 seconds per request executing a slow SQL query, it makes no sense to try to improve performance by tweaking your code. You need to look at your database, make sure tables are indexed properly, rewrite your query, or perhaps denormalize a few tables.
Profiling tools are available for PHP, C/C++, Java, and many other languages. It takes some time to get started with one of these tools, but it’s well worth it.
May 30th, 2007 at 9:34 pm
reminds me of the BH site, I totally understand what it’s like to look at code and just be lost!
May 30th, 2007 at 9:53 pm
Hah! The BH site had some serious issues, that’s for sure. Every time I looked at that code I wanted to stab myself.
That brings up an interesting point though: crappy spaghetti code encourages future coders to write more crappy spaghetti code. If you can’t figure out how to modify the existing code the only solution is to write some hack that probably duplicates functionality, and definitely won’t make sense to the _next_ programmer who comes along after you… and the cycle continues. Conversely, well written and elegant code often encourages future programmers to write more elegant code.
June 1st, 2007 at 1:10 am
This post is very informative
June 1st, 2007 at 11:28 am
Thank you! The title “Premature Optimization: A Serious Problem” is already very informative!
I’m “addicted” on code optimization, but it’s a very very serious problem because sometimes it takes me a week to implement codes that I know I could do in a couple of hours…
June 24th, 2007 at 9:47 pm
Yes… I used to worry about the performance of my little chunks of code until I used a profiler and realized RARELY was my code the problem. It usually ends up being some call to some external system somewhere that bogs performance… not whether you used Stringbuffer or Stringbuilder (java). This whole thing also plays into my post about Smart Programmers Being Bad For Business
August 15th, 2007 at 8:21 pm
[...] The extension has a number of more advanced features that allow developers to perform code coverage analysis, collect profiling information, and debug scripts interactively. The profiling functionality is particularly useful. The profiler uses a common output file format, allowing you to use tools like KCacheGrind to quickly find bottlenecks in your code. A good profiler is an essential tool for any serious developer, as it allows you to properly optimize your code while avoiding the hazards of premature optimization. [...]
August 17th, 2007 at 12:02 am
[...] The extension has a number of more advanced features that allow developers to perform code coverage analysis, collect profiling information, and debug scripts interactively. The profiling functionality is particularly useful. The profiler uses a common output file format, allowing you to use tools like KCacheGrind to quickly find bottlenecks in your code. A good profiler is an essential tool for any serious developer, as it allows you to properly optimize your code while avoiding the hazards of premature optimization. [...]
August 17th, 2007 at 11:52 pm
[...] The extension has a number of more advanced features that allow developers to perform code coverage analysis, collect profiling information, and debug scripts interactively. The profiling functionality is particularly useful. The profiler uses a common output file format, allowing you to use tools like KCacheGrind to quickly find bottlenecks in your code. A good profiler is an essential tool for any serious developer, as it allows you to properly optimize your code while avoiding the hazards of premature optimization. [...]
August 20th, 2007 at 9:06 am
[...] The extension has a number of more advanced features that allow developers to perform code coverage analysis, collect profiling information, and debug scripts interactively. The profiling functionality is particularly useful. The profiler uses a common output file format, allowing you to use tools like KCacheGrind to quickly find bottlenecks in your code. A good profiler is an essential tool for any serious developer, as it allows you to properly optimize your code while avoiding the hazards of premature optimization. [...]
September 3rd, 2007 at 12:02 am
[...] The extension has a number of more advanced features that allow developers to perform code coverage analysis, collect profiling information, and debug scripts interactively. The profiling functionality is particularly useful. The profiler uses a common output file format, allowing you to use tools like KCacheGrind to quickly find bottlenecks in your code. A good profiler is an essential tool for any serious developer, as it allows you to properly optimize your code while avoiding the hazards of premature optimization. [...]
September 10th, 2007 at 6:00 am
[...] 这个扩展有很多更先进的功能,允许开发人员进行代码覆盖率分析,收集分析信息以及交互式地调试脚本。profiling functionality 功能尤其有用。分析器使用一个普通的输出文件格式,允许你使用象 KCacheGrind 这样的工具快速发现你代码中的瓶颈。对任何严肃的开发人员而言,一个好的分析器是基本工具,它使得你妥善优化你的代码,同时避免过早优化带来的危害。 [...]
September 10th, 2007 at 6:40 pm
[...] The extension has a number of more advanced features that allow developers to perform code coverage analysis, collect profiling information, and debug scripts interactively. The profiling functionality is particularly useful. The profiler uses a common output file format, allowing you to use tools like KCacheGrind to quickly find bottlenecks in your code. A good profiler is an essential tool for any serious developer, as it allows you to properly optimize your code while avoiding the hazards of premature optimization. [...]
September 15th, 2007 at 9:45 am
[...] 这个扩展有很多更先进的功能,允许开发人员进行代码覆盖率分析,收集分析信息以及交互式地调试脚本。profiling functionality 功能尤其有用。分析器使用一个普通的输出文件格式,允许你使用象 KCacheGrind 这样的工具快速发现你代码中的瓶颈。对任何严肃的开发人员而言,一个好的分析器是基本工具,它使得你妥善优化你的代码,同时避免过早优化带来的危害。 [...]
September 24th, 2007 at 1:20 am
[...] 这个扩展有很多更先进的功能,允许开发人员进行代码覆盖率分析,收集分析信息以及交互式地调试脚本。profiling functionality 功能尤其有用。分析器使用一个普通的输出文件格式,允许你使用象 KCacheGrind 这样的工具快速发现你代码中的瓶颈。对任何严肃的开发人员而言,一个好的分析器是基本工具,它使得你妥善优化你的代码,同时避免过早优化带来的危害 。 [...]
September 28th, 2007 at 12:26 am
[...] 这个扩展有很多更先进的功能,允许开发人员进行代码覆盖率分析,收集分析信息以及交互式地调试脚本。profiling functionality 功能尤其有用。分析器使用一个普通的输出文件格式,允许你使用象 KCacheGrind 这样的工具快速发现你代码中的瓶颈。对任何严肃的开发人员而言,一个好的分析器是基本工具,它使得你妥善优化你的代码,同时避免过早优化带来的危害。 [...]
July 29th, 2008 at 12:50 pm
[...] The extension has a number of more advanced features that allow developers to perform code coverage analysis, collect profiling information, and debug scripts interactively. The profiling functionality is particularly useful. The profiler uses a common output file format, allowing you to use tools like KCacheGrind to quickly find bottlenecks in your code. A good profiler is an essential tool for any serious developer, as it allows you to properly optimize your code while avoiding the hazards of premature optimization. [...]