It’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.