This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.
Improving .NET Application Performance and Scalability
J.D. Meier, Srinath Vasireddy, Ashish Babbar, and Alex Mackman
Microsoft Corporation
May 2004
Related Links
Home Page for Improving .NET Application Performance and Scalability
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
Check
Description
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
Check
Description
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
Check
Description
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
Check
Description
If you need to pin buffers, allocate them at startup.
Threading
Check
Description
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
Check
Description
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
Check
Description
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
Check
Description
Avoid frequent boxing and unboxing overhead.
Measure boxing overhead.
Use DirectCast in your Visual Basic .NET code.
Exception Management
Check
Description
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
Check
Description
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
Check
Description
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
Check
Description
Prefer arrays to collections unless you need functionality.
Use strongly typed arrays.
Use jagged arrays instead of multidimensional arrays.
Collections
Check
Description
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
Check
Description
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
Check
Description
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
Check
Description
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)
Check
Description
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.
Retired Content
This content is outdated and is no longer being maintained. It is provided as a courtesy for individuals who are still using these technologies. This page may contain URLs that were valid when originally published, but now link to sites or pages that no longer exist.