Performance rules

Performance rules support high-performance libraries and applications.

In this section

Rule Description
CA1802: Use Literals Where Appropriate A field is declared static and read-only (Shared and ReadOnly in Visual Basic), and is initialized with a value that is computable at compile time. Because the value that is assigned to the targeted field is computable at compile time, change the declaration to a const (Const in Visual Basic) field so that the value is computed at compile time instead of at run time.
CA1805: Do not initialize unnecessarily The .NET runtime initializes all fields of reference types to their default values before running the constructor. In most cases, explicitly initializing a field to its default value is redundant, which adds to maintenance costs and may degrade performance (such as with increased assembly size).
CA1806: Do not ignore method results A new object is created but never used, or a method that creates and returns a new string is called and the new string is never used, or a Component Object Model (COM) or P/Invoke method returns an HRESULT or error code that is never used.
CA1810: Initialize reference type static fields inline When a type declares an explicit static constructor, the just-in-time (JIT) compiler adds a check to each static method and instance constructor of the type to make sure that the static constructor was previously called. Static constructor checks can decrease performance.
CA1812: Avoid uninstantiated internal classes An instance of an assembly-level type is not created by code in the assembly.
CA1813: Avoid unsealed attributes .NET provides methods for retrieving custom attributes. By default, these methods search the attribute inheritance hierarchy. Sealing the attribute eliminates the search through the inheritance hierarchy and can improve performance.
CA1814: Prefer jagged arrays over multidimensional A jagged array is an array whose elements are arrays. The arrays that make up the elements can be of different sizes, which can result in less wasted space for some sets of data.
CA1815: Override equals and operator equals on value types For value types, the inherited implementation of Equals uses the Reflection library and compares the contents of all fields. Reflection is computationally expensive, and comparing every field for equality might be unnecessary. If you expect users to compare or sort instances, or to use instances as hash table keys, your value type should implement Equals.
CA1819: Properties should not return arrays Arrays that are returned by properties are not write-protected, even if the property is read-only. To keep the array tamper-proof, the property must return a copy of the array. Typically, users will not understand the adverse performance implications of calling such a property.
CA1820: Test for empty strings using string length Comparing strings by using the String.Length property or the String.IsNullOrEmpty method is significantly faster than using Equals.
CA1821: Remove empty finalizers Whenever you can, avoid finalizers because of the additional performance overhead that is involved in tracking object lifetime. An empty finalizer incurs added overhead without any benefit.
CA1822: Mark members as static Members that do not access instance data or call instance methods can be marked as static (Shared in Visual Basic). After you mark the methods as static, the compiler will emit nonvirtual call sites to these members. This can give you a measurable performance gain for performance-sensitive code.
CA1823: Avoid unused private fields Private fields were detected that do not appear to be accessed in the assembly.
CA1824: Mark assemblies with NeutralResourcesLanguageAttribute The NeutralResourcesLanguage attribute informs the Resource Manager of the language that was used to display the resources of a neutral culture for an assembly. This improves lookup performance for the first resource that you load and can reduce your working set.
CA1825: Avoid zero-length array allocations Initializing a zero-length array leads to unnecessary memory allocation. Instead, use the statically allocated empty array instance by calling Array.Empty. The memory allocation is shared across all invocations of this method.
CA1826: Use property instead of Linq Enumerable method Enumerable LINQ method was used on a type that supports an equivalent, more efficient property.
CA1827: Do not use Count/LongCount when Any can be used Count or LongCount method was used where Any method would be more efficient.
CA1828: Do not use CountAsync/LongCountAsync when AnyAsync can be used CountAsync or LongCountAsync method was used where AnyAsync method would be more efficient.
CA1829: Use Length/Count property instead of Enumerable.Count method Count LINQ method was used on a type that supports an equivalent, more efficient Length or Count property.
CA1830: Prefer strongly-typed Append and Insert method overloads on StringBuilder Append and Insert provide overloads for multiple types beyond System.String. When possible, prefer the strongly-typed overloads over using ToString() and the string-based overload.
CA1831: Use AsSpan instead of Range-based indexers for string when appropriate When using a range-indexer on a string and implicitly assigning the value to a ReadOnlySpan<char> type, the method Substring will be used instead of Slice, which produces a copy of requested portion of the string.
CA1832: Use AsSpan or AsMemory instead of Range-based indexers for getting ReadOnlySpan or ReadOnlyMemory portion of an array When using a range-indexer on an array and implicitly assigning the value to a ReadOnlySpan<T> or ReadOnlyMemory<T> type, the method GetSubArray will be used instead of Slice, which produces a copy of requested portion of the array.
CA1833: Use AsSpan or AsMemory instead of Range-based indexers for getting Span or Memory portion of an array When using a range-indexer on an array and implicitly assigning the value to a Span<T> or Memory<T> type, the method GetSubArray will be used instead of Slice, which produces a copy of requested portion of the array.
CA1834: Use StringBuilder.Append(char) for single character strings StringBuilder has an Append overload that takes a char as its argument. Prefer calling the char overload to improve performance.
CA1835: Prefer the 'Memory'-based overloads for 'ReadAsync' and 'WriteAsync' 'Stream' has a 'ReadAsync' overload that takes a 'Memory<Byte>' as the first argument, and a 'WriteAsync' overload that takes a 'ReadOnlyMemory<Byte>' as the first argument. Prefer calling the memory based overloads, which are more efficient.
CA1836: Prefer IsEmpty over Count when available Prefer IsEmpty property that is more efficient than Count, Length, Count<TSource>(IEnumerable<TSource>) or LongCount<TSource>(IEnumerable<TSource>) to determine whether the object contains or not any items.
CA1837: Use Environment.ProcessId instead of Process.GetCurrentProcess().Id Environment.ProcessId is simpler and faster than Process.GetCurrentProcess().Id.
CA1838: Avoid StringBuilder parameters for P/Invokes Marshaling of StringBuilder always creates a native buffer copy, resulting in multiple allocations for one marshaling operation.
CA1841: Prefer Dictionary Contains methods Calling Contains on the Keys or Values collection may often be more expensive than calling ContainsKey or ContainsValue on the dictionary itself.