Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
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 LengthorCountproperty. | 
| 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 Appendoverload that takes acharas its argument. Prefer calling thecharoverload 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 IsEmptyoverCountwhen available | Prefer IsEmptyproperty that is more efficient thanCount,Length, Count<TSource>(IEnumerable<TSource>) or LongCount<TSource>(IEnumerable<TSource>) to determine whether the object contains or not any items. | 
| CA1837: Use Environment.ProcessIdinstead ofProcess.GetCurrentProcess().Id | Environment.ProcessIdis simpler and faster thanProcess.GetCurrentProcess().Id. | 
| CA1838: Avoid StringBuilderparameters for P/Invokes | Marshalling of StringBuilderalways creates a native buffer copy, resulting in multiple allocations for one marshalling operation. | 
| CA1839: Use Environment.ProcessPath instead of Process.GetCurrentProcess().MainModule.FileName | Environment.ProcessPathis simpler and faster thanProcess.GetCurrentProcess().MainModule.FileName. | 
| CA1840: Use Environment.CurrentManagedThreadId instead of Thread.CurrentThread.ManagedThreadId | Environment.CurrentManagedThreadIdis more compact and efficient thanThread.CurrentThread.ManagedThreadId. | 
| CA1841: Prefer Dictionary Contains methods | Calling Containson theKeysorValuescollection may often be more expensive than callingContainsKeyorContainsValueon the dictionary itself. | 
| CA1842: Do not use 'WhenAll' with a single task | Using WhenAllwith a single task may result in performance loss. Await or return the task instead. | 
| CA1843: Do not use 'WaitAll' with a single task | Using WaitAllwith a single task may result in performance loss. Await or return the task instead. | 
| CA1844: Provide memory-based overrides of async methods when subclassing 'Stream' | To improve performance, override the memory-based async methods when subclassing 'Stream'. Then implement the array-based methods in terms of the memory-based methods. | 
| CA1845: Use span-based 'string.Concat' | It is more efficient to use AsSpanandstring.Concat, instead ofSubstringand a concatenation operator. | 
| CA1846: Prefer AsSpanoverSubstring | AsSpanis more efficient thanSubstring.Substringperforms an O(n) string copy, whileAsSpandoes not and has a constant cost.AsSpanalso does not perform any heap allocations. | 
| CA1847: Use char literal for a single character lookup | Use String.Contains(char)instead ofString.Contains(string)when searching for a single character. | 
| CA1848: Use the LoggerMessage delegates | For improved performance, use the LoggerMessagedelegates. | 
| CA1849: Call async methods when in an async method | In a method which is already asynchronous, calls to other methods should be to their async versions, where they exist. | 
| CA1850: Prefer static HashDatamethod overComputeHash | It's more efficient to use the static HashDatamethod over creating and managing aHashAlgorithminstance to callComputeHash. | 
| CA1851: Possible multiple enumerations of IEnumerablecollection | Possible multiple enumerations of IEnumerablecollection. Consider using an implementation that avoids multiple enumerations. | 
| CA1852: Seal internal types | A type that's not accessible outside its assembly and has no subtypes within its containing assembly is not sealed. | 
| CA1853: Unnecessary call to 'Dictionary.ContainsKey(key)' | There's no need to guard Dictionary.Remove(key)withDictionary.ContainsKey(key). Dictionary<TKey,TValue>.Remove(TKey) already checks whether the key exists and doesn't throw if it doesn't exist. | 
| CA1854: Prefer the 'IDictionary.TryGetValue(TKey, out TValue)' method | Prefer 'TryGetValue' over a Dictionary indexer access guarded by a 'ContainsKey' check. 'ContainsKey' and the indexer both look up the key, so using 'TryGetValue' avoids the extra lookup. | 
| CA1855: Use Span<T>.Clear() instead of Span<T>.Fill() | It's more efficient to call Span<T>.Clear() than to call Span<T>.Fill(T) to fill the elements of the span with a default value. | 
| CA1856: Incorrect usage of ConstantExpected attribute | The ConstantExpectedAttribute attribute is not applied correctly on a parameter. | 
| CA1857: The parameter expects a constant for optimal performance | An invalid argument is passed to a parameter that's annotated with ConstantExpectedAttribute. | 
| CA1858: Use StartsWith instead of IndexOf | It's more efficient to call String.StartsWith than to call String.IndexOf to check whether a string starts with a given prefix. | 
| CA1859: Use concrete types when possible for improved performance | Code uses interface types or abstract types, leading to unnecessary interface calls or virtual calls. | 
| CA1860: Avoid using 'Enumerable.Any()' extension method | It's more efficient and clearer to use Length,Count, orIsEmpty(if possible) than to call Enumerable.Any to determine whether a collection type has any elements. | 
| CA1861: Avoid constant arrays as arguments | Constant arrays passed as arguments are not reused which implies a performance overhead. Consider extracting them to 'static readonly' fields to improve performance. | 
| CA1862: Use the 'StringComparison' method overloads to perform case-insensitive string comparisons | When code calls ToLower() or ToUpper() to perform a case-insensitive string comparison, an unnecessary allocation is performed. | 
| CA1863: Use 'CompositeFormat' | To reduce the formatting cost, cache and use a CompositeFormat instance as the argument to String.FormatorStringBuilder.AppendFormat. | 
| CA1864: Prefer the 'IDictionary.TryAdd(TKey, TValue)' method | Both Dictionary<TKey,TValue>.ContainsKey(TKey) and Dictionary<TKey,TValue>.Add perform a lookup, which is redundant. It's is more efficient to call Dictionary<TKey,TValue>.TryAdd, which returns a boolindicating if the value was added or not.TryAdddoesn't overwrite the key's value if the key is already present. | 
| CA1865-CA1867: Use char overload | The char overload is a better performing overload for a string with a single char. | 
| CA1868: Unnecessary call to 'Contains' for sets | Both ISet<T>.Add(T) and ICollection<T>.Remove(T) perform a lookup, which makes it redundant to call ICollection<T>.Contains(T) beforehand. It's more efficient to call Add(T) or Remove(T) directly, which returns a Boolean value indicating whether the item was added or removed. | 
| CA1869: Cache and reuse 'JsonSerializerOptions' instances | Using a local instance of JsonSerializerOptions for serialization or deserialization can substantially degrade the performance of your application if your code executes multiple times, since System.Text.Json internally caches serialization-related metadata into the provided instance. | 
| CA1870: Use a cached 'SearchValues' instance | Using a cached SearchValues<T> instance is more efficient than passing values to 'IndexOfAny' or 'ContainsAny' directly. | 
| CA1871: Do not pass a nullable struct to 'ArgumentNullException.ThrowIfNull' | 'ArgumentNullException.ThrowIfNull' accepts an 'object', so passing a nullable struct might cause the value to be boxed. | 
| CA1872: Prefer 'Convert.ToHexString' and 'Convert.ToHexStringLower' over call chains based on 'BitConverter.ToString' | Use Convert.ToHexString or Convert.ToHexStringLower when encoding bytes to a hexadecimal string representation. These methods are more efficient and allocation-friendly than using BitConverter.ToString in combination with String.Replace to replace dashes and String.ToLower. | 
| CA1873: Avoid potentially expensive logging | When logging methods are called, their arguments are evaluated regardless of whether the logging level is enabled. This can result in expensive operations being executed even when the log message won't be written. For better performance, guard expensive logging calls with a check to IsEnabled or use the LoggerMessagepattern. | 
| CA1874: Use 'Regex.IsMatch' | Regex.IsMatch is simpler and faster than Regex.Match(...).Success. | 
| CA1875: Use 'Regex.Count' | Regex.Count is simpler and faster than Regex.Matches(...).Count. | 
							
							
								Collaborate with us on GitHub
							
						
						
							The source for this content can be found on GitHub, where you can also create and review issues and pull requests. For more information, see our contributor guide.