.NET Framework 1.1 Performance Checklist
From Guidance Share
J.D. Meier, Srinath Vasireddy, Ashish Babbar, Rico Mariani, and Alex Mackman
[edit]
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.
[edit]
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.
[edit]
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.
[edit]
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.
[edit]
Pinning
- If you need to pin buffers, allocate them at startup.
[edit]
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.
[edit]
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.
[edit]
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.
[edit]
Boxing and Unboxing
- Avoid frequent boxing and unboxing overhead.
- Measure boxing overhead.
- Use DirectCast in your Visual Basic .NET code.
[edit]
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.
[edit]
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.
[edit]
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.
[edit]
Arrays
- Prefer arrays to collections unless you need functionality.
- Use strongly typed arrays.
- Use jagged arrays instead of multidimensional arrays.
[edit]
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.
[edit]
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.
[edit]
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.
[edit]
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.
[edit]
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.