.NET Framework 2.0 Performance Checklist

From Guidance Share

Jump to: navigation, search

- J.D. Meier, Srinath Vasireddy, Ashish Babbar, and Alex Mackman

Contents

Design Considerations

  • Design for efficient resource management.
  • Reduce boundary crossings.
  • Prefer single large assemblies rather than multiple smaller assemblies.
  • Factor code by logical layers.
  • Treat threads as a shared resource.
  • Design for efficient exception management.

Class Design Considerations

  • Do not make classes thread safe by default.
  • Consider using the sealed keyword.
  • Consider the tradeoffs of using virtual members.
  • Consider using overloaded methods.
  • Consider overriding the Equals method for value types.
  • Know the cost of accessing a property.
  • Consider private versus public member variables.
  • Limit the use of volatile fields.

Garbage Collection Guidelines

  • Identify and analyze your application's allocation profile.
  • Avoid calling GC.Collect.
  • Consider weak references with cached data.
  • Prevent the promotion of short-lived objects.
  • Set unneeded member variables to Null before making long-running calls.
  • Minimize hidden allocations.
  • Avoid or minimize complex object graphs.
  • Avoid preallocating and chunking memory.

Finalize and Dispose

  • Call Close or Dispose on objects that support it.
  • Use the using statement in Microsoft® C# and Try/Finally blocks in Microsoft Visual Basic®.NET to ensure Dispose is called.
  • Do not implement Finalize unless required.
  • Implement Finalize only if you hold unmanaged resources across client calls.
  • Move the finalization burden to the leaves of object graphs.
  • If you implement Finalize, implement IDisposable.
  • If you implement Finalize and Dispose, use the Dispose pattern.
  • Suppress finalization in your Dispose method.
  • Allow Dispose to be called multiple times.
  • Call Dispose on base classes and on IDisposable members.
  • Keep finalizer code simple to prevent blocking.
  • Provide thread-safe cleanup code only if your type is thread-safe.

Pinning

* If you need to pin buffers, allocate them at startup.

Threading

  • Minimize thread creation.
  • Use the thread pool when you need threads.
  • Use a Timer to schedule periodic tasks.
  • Consider parallel versus synchronous tasks.
  • Do not use Thread.Abort to terminate other threads.
  • Do not use Thread.Suspend and Thread.Resume to pause threads.

Asynchronous Calls

  • Consider client-side asynchronous calls for UI responsiveness.
  • Use asynchronous methods on the server for I/O bound operations.
  • Avoid asynchronous calls that do not add parallelism.

Locking and Synchronization

  • Determine if you need synchronization.
  • Determine the approach.
  • Determine the scope of your approach.
  • Acquire locks late and release them early.
  • Avoid locking and synchronization unless required.
  • Use granular locks to reduce contention.
  • Avoid excessive fine-grained locks.
  • Avoid making thread safety the default for your type.
  • Use the fine grained lock (C#) statement instead of Synchronized.
  • Avoid locking "this".
  • Coordinate multiple readers and single writers by using ReaderWriterLock instead of lock.
  • Do not lock the type of the objects to provide synchronized access.

Boxing and Unboxing

  • Avoid frequent boxing and unboxing overhead.
  • Measure boxing overhead.
  • Use DirectCast in your Visual Basic .NET code.

Exception Management

  • Do not use exceptions to control application flow.
  • Use validation code to avoid unnecessary exceptions.
  • Use the finally block to ensure resources are released.
  • Replace Visual Basic .NET On Error Goto code with exception handling.
  • Do not catch exceptions that you cannot handle.
  • Be aware that rethrowing is expensive.
  • Preserve as much diagnostic information as possible in your exception handlers.
  • Use performance monitor to monitor common language runtime (CLR) exceptions.

Iterating and Looping

  • Avoid repetitive field or property access.
  • Optimize or avoid expensive operations within loops.
  • Copy frequently called code into the loop.
  • Consider replacing recursion with looping.
  • Use for instead of foreach in performance-critical code paths.

String Operations

  • Avoid inefficient string concatenation.
  • Use + when the number of appends is known.
  • Use StringBuilder when the number of appends is unknown.
  • Treat StringBuilder as an accumulator.
  • Use the overloaded Compare method for case-insensitive string comparisons.

Arrays

  • Prefer arrays to collections unless you need functionality.
  • Use strongly typed arrays.
  • Use jagged arrays instead of multidimensional arrays.

Collections

  • Analyze your requirements before choosing the collection type.
  • Initialize collections to the right size when you can.
  • Consider enumerating overhead.
  • Prefer to implement IEnumerable with optimistic concurrency.
  • Consider boxing overhead.
  • Consider for instead of foreach.
  • Implement strongly typed collections to prevent casting overhead.

Reflection and Late Binding

  • Prefer early binding and explicit types rather than reflection.
  • Avoid late binding.
  • Avoid using System.Object in performance critical code paths.
  • Enable Option Explicit and Option Strict in Visual Basic.NET.

Code Access Security

  • Consider SuppressUnmanagedCodeSecurity for performance-critical, trusted scenarios.
  • Prefer declarative demands rather than imperative demands.
  • Consider using link demands rather than full demands for performance - critical, trusted scenarios.

Working Set Considerations

  • Load only the assemblies you need.
  • Consider assemblies that are being loaded as side effects.
  • Reduce the number of application domains, and/or make assemblies shared assemblies.
  • Reduce the number of threads.

Native Image Generator (Ngen.exe)

  • Scenarios where startup time is paramount should consider Ngen.exe for their startup path.
  • Scenarios that will benefit from the ability to share assemblies should adopt Ngen.exe.
  • Scenarios with limited or no sharing should not use Ngen.exe.
  • Do not use Ngen.exe for ASP.NET version 1.0 and 1.1.
  • Consider Ngen.exe for ASP.NET version 2.0.
  • Measure performance with and without Ngen.exe.
  • Regenerate your image when you ship new versions.
  • Choose an appropriate base address.
  • Install assemblies in the GAC if you want to use NGEN to get the best performance.
  • A setup application for an update of a library assembly should run the 'Ngen.exe update' command.

Resources

Personal tools