Kick-Start Your Application’s Performance

This book goes through hundreds of details that may be a problem in your application, but if you are just getting started, here is a general outline of how you can proceed and analyze your own program’s performance.

Define Metrics

  • Define the metrics you are interested in.
  • Decide what kind of statistics you need: average, min, max, percentiles, or more complex.
  • What are the resource constraints you are operating under? Possible values include, but are not limited to: CPU, memory usage, allocation rate, network I/O, disk usage, disk write rate, to name a few.
  • What are the goals for each metric or resource?

Analyze CPU Usage

  • Use PerfView or Visual Studio Standalone Profiler to get a CPU profile of your application doing work.
  • Analyze the stacks for functions that stand out.
  • Is data processing taking a long time?
    • Can you change your data structure to be in a format that requires less processing? For example, instead of parsing XML, use a simple binary serialization format.
    • Are there alternate APIs?
    • Can you parallelize the work with Task delegates or Parallel.For?

Analyze Memory Usage

  • Consider the right type of GC:
    • Server: Your program is the only significant application on the machine and needs the lowest possible latency for GCs.
    • Workstation: You have a UI or share the machine with other important process.
  • Profile memory with PerfView:
    • Check results for top allocators—are they expected and acceptable?
    • Pay close attention to the Large Object allocations.
  • If gen 2 GCs happen too often:
    • Are there a lot of LOH allocations? Remove or pool these objects.
    • Is object promotion high? Reduce object lifetime so that lower generation GCs can collect them. Allocate objects only when needed and null them out when no longer needed.
    • If objects are living too long, pool them.
  • If gen 2 GCs take too long:
    • Consider using GC notifications to get a signal when GC is about to start. Use this opportunity to stop processing.
    • Reduce frequency of full GCs with lower object promotion and fewer LOH allocations.
  • If you have high number of gen 0/1 GCs:
    • Look at highest area of allocations in the profile. Find ways to reduce the need for memory allocations.
    • Minimize object lifetime.
  • If gen 0/1 GCs have a high pause time:
    • Reduce allocations overall.
    • Minimize object lifetime.
    • Are objects being pinned? Remove these if possible, or reduce the scope of the pinning.
    • Reduce object complexity by removing references between objects.
  • If the LOH is growing large:
    • Check for fragmentation with WinDbg or CLR Profiler.
    • Compact the large object heap periodically.
    • Check for object pools with unbounded growth.

Analyze JIT

  • If your startup time is long:
    • Is it really because of JIT? Loading application-specific data is a more common cause of long startup times. Make sure it really is JIT.
    • Use PerfView to analyze which methods take a long time to JIT.
    • Use Profile Optimization to speed up JIT on application load.
    • Consider using NGEN.
    • Consider a custom warmup solution that exercises your code.
  • Are there methods showing up in the profile that you would expect to be inlined?
    • Look at methods for inlining blockers such as loops, exception handling, recursion, and more.

Analyze Asynchronous Performance

  • Use PerfView to determine if there are a high number of contentions.
    • Remove contentions by restructuring the code to need fewer locks.
    • Use Interlocked methods or hybrid locks where necessary.
  • Capture Thread Time events with PerfView to see where time is being spent. Analyze these areas of the code to ensure that threads are not blocking on I/O.
    • You may have to significantly change your program to be more asynchronous at every level to avoid waiting on Task objects or I/O.
    • Ensure you are using asynchronous stream APIs.
  • Does your program take a while before it starts using the thread pool efficiently? This can manifest itself as initial slowness that goes away within a few minutes.
    • Make sure the minimum thread pool size is adequate for your workload.
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset