One of my passions is optimization. There's no code related task I like more than making something run better, faster, snappier -- from tweaking UI registry keys to stripping out crap code -- I want results. Usually if something is noticeably slow on the user's end, there's something fundamentally wrong that can be made faster -- a lot faster.
Why do I love optimization? It's because it's the opposite of a thankless job. Everyone thanks you. Your sales team thanks you. Project Managers thank you. Executive management drools over your optimization report -- they can take it straight to the bank. Product leads take your report and put it into the release notes. Or a press release. You're the hero! And it's downright fun.
Long story short, my team was recently assigned optimization targets for our app for increasing user capacity (+30%) and decreasing startup and postback times (-20%). During the iteration, the rest of the team was sucked away to emergency projects, and I singlehandedly blew so far past the targets I couldn't even see them anymore. Final optimizations included 100% increased concurrent user load and a 97% reduction in postback execution time. Application startup time was decreased by 40%. Total code changes was 40 lines. Call it precision strike coding. Toss in one nicely formatted "before and after" optimization report, and I'd say it's been a pretty good couple of weeks.
But you need to know what you're doing, and where to get started. You can't simply sit down in front of the code and start randomly caching things or turning every '+' operator into a StringBuilder. (Note: that's not a good idea anyway). But if you get familiar with the following tools, you'll already know where to start. So without further ado…
If you want to optimize, you need to have an arsenal of tools to troubleshoot and profile your app. You should be familiar with as many of these tools as possible.
Recommended: RedGate Ants (14-day free trial, $295 to purchase)
Pretty much no exceptions here -- you have to have a profiler. It's extremely time consuming and ugly to start adding TimeSpan calculations around every block of code in your app. For the amount of time it would take to track down one slow line of code "manually", you could have run four profiler sessions and have your top ten "target list" ready to go, made yourself a sandwich and played a game of foosball. Not only that, but profilers will identify fast blocks of code that are getting executed ridiculous numbers of times, making them slow overall.
Since I've used RedGate's Ants Profiler pretty much exclusively, that's all I can recommend here, but others exist. RedGate is great at profiling code, but I find their memory profiling to be pretty lackluster, so if I need to dig into memory I'll generally fire up Windbg (see further down).
Recommended: NeoLoad (10 "virtual user" Free Trial but fairly expensive to purchase)
Also good: WAST (Free)
You need to be able to load test your application to see how it performs. When does it crash? How many users does it support? How does your memory, disks, network and processors hold up? Load testing uncovers errors you couldn't even dream of by looking at your code -- concurrency issues, how your application performs when resources are unavailable, etc.
Load testing tools pose a problem however, because there is a huge gap between free tools and proprietary tools. Here's a list of some of the ones I know for Windows/IIS:
TinyGet (Free) - run some HTTP requests sequentially in a loop. Part of IIS 6 Resource Toolkit
WAST (Free)- an oldie but a goodie -- record basic web browsing and simulate lots of users
MS ACT -- (Application Center Test) -- Next generation from WAST, allows for dynamic variables. It comes with Enterprise Edition level MSDN subscription. Thanks to mike for pointing it out.
NeoLoad - good bang for the buck, all the functionality you'll need for even complex AJAX applications, but not cheap and has a predatory pricing model shared by higher end software
Visual Studio Team Edition for Testers -- you can buy a lot of NeoLoad virtual users for this kind of cash.
HP LoadRunner -- you could probably hire a thousand testers, buy them all computers and have them generate load manually for what you'd pay for this kind of software.
The problem is that the free stuff (TinyGet, WAST) is next to useless for testing sessions and AJAX apps, they're just not built to handle it. I've recently gotten a lot of experience using Neoload and it's pretty good software with fantastic support behind it -- you can record complex user sessions with many dynamic parameters, multiple viewstates and have multiple recorded sessions make up a "population" of users to test your app under a broad range of conditions. It also hooks into the perfmon API to give you flexible reporting and graphs. Unfortunately they charge per "virtual user" you want to have running, and it's not real cheap. Small businesses may find it worthwhile depending on the situation. Freelancers may want to stick with WAST, look at some other options, or roll their own.
The top range stuff is for medium-very large businesses that can shell out the dough, and I don't have any experience with them. For the money, they'd better be good!
Recommended: Performance Monitor (perfmon.exe) (Free)
Also good: NeoLoad
At what point does your app spike the CPU? How's that CLR request queue going? What's your heap memory look like? Microsoft's perfmon API is very rich and if you don't have a custom app that hooks into it already, simply type "perfmon.exe" at the command prompt and you have everything you need in Microsoft's simple MMC app. You can monitor as many machines as necessary all in the same window or log. Experiment with recording counter log files and replaying them -- this data can be exported and included for that extra-demanding CTO. If you're unfamiliar with perfmon, play around with it -- it's not too hard to figure out even though the interface is a bit dated.
Recommended: Fiddler2 (Free)
Optimizing your AJAX app? Confused about how chatty your application is being? You need to be able to see exactly what's going between client and server -- requests, responses, headers, what's compressed and what isn't. Enter Fiddler2 -- this little proxy server sits between IE and any web page and records all the traffic, and reports it for you in an easy to see format. Tip: if you're looking at your pages on your local machine, use http://machinename instead of http://localhost, since IE ignores going through a proxy for localhost addresses.
Fiddler2 is especially useful for ASP.Net apps because it's not always clear exactly what kind of HTML is being generated by webcontrols.
A good debugger/memory dump analyzer is probably the single most powerful tool in your arsenal if you know how to use it. Windbg will let you take a snapshot of your application as it's running or when it crashes, and you can quickly narrow down what's causing crashes, hangs, excessive memory usage, or identify potential optimizations. You can explore the runtime stacks, native and CLR, see what every thread was doing, and see what's in every memory address on your heaps. If you've never used Windbg, there are fantastic lab-style tutorials at Tess' blog at MSDN. These tutorials will also introduce you to perfmon and tinyget.
FXCop can be a useful tool but depending on your environment, it might be more trouble than it's worth. Simply put, it scans your code looking for bad coding practices and comes up with a report about how sloppy you are. Unfortunately, some of the default rules may not apply to your development environment, but with a little effort you can certainly weed out the rules you don't need and make it more useful for your team.
Recommended: Fritz Onion's Viewstate Decoder (Free)
At some point most ASP.Net apps undergo a Viewstate optimization. Let's face it, Viewstate can be downright disgusting. If you're jumping into the middle of an application, it's helpful to have some guidance on where the hell it's all coming from. Just copy and paste it into a Viewstate decoder and you might find a ton of clues.
As every experienced coder knows, sometimes, you just don't want to look at something in your IDE. You just want to open a file fast and be done with it. I've used UltraEdit for a long time and it has great features, useful for optimization. For example, you can copy a recorded request from Fiddler, paste it into Ultraedit, and immediately count how many times your ultra-long image pathname occurs, and immediately know how many bytes you can shave out of your file. It has quick and easy syntax highlighting for pretty much any programming language, line numbers, and tracks the file and asks to reload it if it detects changes. It also detects blocks of code or xml for expanding/collapsing, and hundreds of other features.
Although I didn't include Lutz Roeder's Reflector in the list since I don't find that I use it that often when I'm debugging, it's something you should always have for easy reference, especially if you're dealing with unfamiliar assemblies.
Good luck optimizing! Remember to spellcheck your optimization report, and don't forget to put in a one page executive summary of what a hero you are.