At Raleigh Code Camp, I had an unfortunately familiar conversation with another developer.
- Me: How often do you profile your application for performance or memory issues?
Him: I don't.
- Me: Really? How do you know if your app has any issues?
- Him: Because I write good code.
I understand this mentality; with experience, you are less likely to encounter obvious performance and memory issues in your own code. You’ve hit the major traps and learned to avoid them. Of course, saying you have no performance or memory issue is like saying you never have bugs. Actually, it’s far worse. Saying you don’t need to profile your code is like saying you don’t need unit tests.
I want to make one thing very clear: Performance and memory management issues are inevitable.
These issues interfere with the user experience, and they can fly under the radar during development due to environmental differences or usage patterns. There are two ways to address these types of issues.
As with bug prevention, the best approach is to specify expected behavior upfront. However, many developers profile in response to a problem that has surfaced. This happened to me a few years ago.
We received multiple bug reports that the application was unstable and caused the users' workstation to slow down. Neither the development team nor quality assurance noticed the problem, nor could they replicate it. After interviewing the users reporting the bugs, we found that these particular users rarely closed their applications or rebooted their workstations. Further investigation on their stations revealed that the application was consuming several gigs of RAM. When the application was first opened, it only consumed a hundred MB of RAM. The application had a memory leak.
Profiling applications reactively is like responding to a bug report, and it is better that the bug didn’t exist in the first place. You may not be able to eliminate every issue upfront, but you can reduce their frequency.
Proactive assessment includes profiling as part of the development process. There are many non-functional requirements that are part of the system, and you should establish use cases for acceptable performance, or responsiveness, and reliability, or probability of failure. In the reactive scenario, the software worked fine at first, but it developed issues the longer it ran. Its reliability was dependent on the length and frequency of its usage.
I'm not suggesting you tweak your code until you maximize performance and reliability. What I do recommend is that you establish your non-functional requirements up-front and regularly profile your solution to ensure it meets these requirements. When the metrics go beyond the acceptable range, you should optimize that particular piece of the system.
Nothing to Lose
Perhaps you think you can’t possibly have a memory or performance issue, like the developer I met in Raleigh. It turns out that you have nothing to lose by profiling your application with JustTrace
. You have thirty days to try it out, so I challenge you to put your application through its paces while analyzing it with JustTrace. You may just be surprised at what you discover!
JustTrace includes helpful information and tips to guide you throughout the profiling process. However, if you prefer a quick guide to get started, I recommend 4 Steps to Profile Your Apps
We have a page for further resources
, and it includes a link to the rough cuts from an e-book I’m working on: The .NET Developer’s Guide to Memory and Performance Profiling
Let us know what you think by visiting the Feedback Portal
Chris thinks profiling with JustTrace is far more enjoyable than reading MS Partition I to determine how the VES behaves in relation to his code. But that’s just crazy talk.