CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Eric Wise

Business & .NET

Optimizing Code - Level 100

There has always been a mini religious war between programmers about code layout/style and when to optimize.  My personal take on this has been put more weight on readability and maintainability over highly condensed, optimized code.  Here's a few thoughts on this subject:

Don't optimize first

In almost all cases I have ever seen, optimizing while writing your first beta of code leads to poor readability and few gains.  There are a variety of load testing suites available out there, what I recommend is to hold off on optimization until the majority of the application is complete.  Then design some intelligent load tests and figure out where your bottlenecks are.  In most cases I have seen, the majority of "slow code" can be tracked down to a few trigger points, generally less than 5% of the code.

On the other hand, if you optimize first, you end up with code that is harder to read and maintain in places where the performance benefit simply isn't worth it.

Trust your compiler

Most modern languages like .NET have compilers that optimize your code for you.  A common mistake I see coders making is that they write poorly readable code in an attempt to optimize things that the compiler would have taken care of anyway.  It is very important that you understand how your compiler works!  DO NOT waste your time optimizing a block of code until you compile it and peek at the compiled code (.NET Reflector rocks for this).  Oftentimes you'll find that the IL language does exactly what you would have done in a re-write.  It would be a shame to change some readable easy code to illegible optimized code and get a 0% increase in performance.

A Few Tips

  • In most business applications the slowest thing you do is access the file structure and the database.  With this in mind make use of caching and if you are going to access the database, try to get as much data as you think you'll need in one shot instead of making x number of calls in a single procedure.
  • The balancing statement for the above is that you should avoid loading data you don't need!
  • If a section of code with database logic is exceptionally slow, check the database first.  Many times it's just a simple thing such as not having an index.
  • Organize your Switch/Case statements logically.  This means putting your most common occurances near the top of the statement so that less evaluations will occur on average before finding the correct case.


Comments

Raymond Lewallen said:

When doing optimizations, remember the 80/20 rule as applied to software engineering: 80% of the work is done in 20% of the code. The other 80% of the code only does 20% of the work.
# April 21, 2005 10:48 AM

jfiorato said:

Do you have an example of the c# compiler optimizations, or do you just mean .NET JIT optimizations? I think all the c# compiler does is remove empty try/catch, try/finally blocks, unused variables and dead branches, things I can't fathom keeping for any reason.
# April 21, 2005 12:41 PM

Eric Wise said:

Here's an example from Code Complete:

sum = 0;
for (row=0; row < rowcount; row++) {
for (column = 0; column < columncount; column++) {
sum = sum + matrix[row][column];
}
}

The following code should be "more efficient" because of how array access works:

sum = 0;
elementPointer = matrix;
lastElementPointer = matrix[rowCount - 1][columnCount - 1] + 1;
while (elementPointer < lastElementPointer) {
sum = sum + *elementPointer++;
}

Pointers are faster than accessing arrays like the top example, however the bottom example is less readable. If you dig into compiler code you'd find that the optimizer turned the top code into pointer code.
# April 21, 2005 12:56 PM

jfiorato said:

Right, so that's a JIT compiler optimization. So how do you get to view that with something like Reflector?
# April 21, 2005 1:13 PM

jfiorato said:

Actually Eric, don't respond to that, I'll figure that out on my own. Thanks for your responses.
# April 21, 2005 1:34 PM

Darrell said:

Along with everything else, I'd like to add MEASURE! Measure performance before to have a baseline, make a change, and measure performance after to see if there is a difference.

Also make sure that you can tell when you're done, ie, you know what is an acceptable performance level. :)
# April 22, 2005 6:41 AM

Jeffrey Palermo said:

I completely agree. I hate asking about a section of code and hearing "This way is more performant", and I know they haven't really done a test, and there is not rational reason to think there is a difference.
# April 22, 2005 7:18 PM

Klok said:

Do you know of any good tools, for finding out which 20% of code, is worth optimizing?

Or is that a matter of spotting where your program is slowing down?
# April 27, 2005 11:01 PM

Eric Wise said:

There's the application test center that comes with visual studio enterprise.

There's also a product called ANTS...
# April 28, 2005 6:57 AM

Sixtieslibber said:

What you have written is probably correct for the applications you are talking about. However, there are many applications--such as occur in scientific simulations--where changing the fundamental algorithm can give order of magnitude speed-up. This may not necessarily be something you are would discover through profiling. I completely agree that you shouldn't worry about trying to beat the compiler. You will end up with code that is harder to read and simply cause problems for the compiler. But please don't forget about algorithms.
# May 23, 2005 2:59 PM

Leave a Comment

(required)  
(optional)
(required)  

Enter the numbers above:
Add
Check out Devlicio.us!

Our Sponsors

Free Tech Publications