Правила производительности

Правила производительности поддерживают высокоэффективные библиотеки и приложения.

В этом разделе

Правило Описание
CA1802: Используйте литеральные значения, где это уместно Поле объявляется статичным и доступным только для чтения (Shared и ReadOnly в Visual Basic) и инициализируется со значением, вычисляемым во время компиляции. Так как значение, назначенное целевому полю, является вычисленным во время компиляции, измените объявление на конст (Const в Visual Basic), чтобы значение вычислялось во время компиляции, а не во время выполнения.
CA1805: не делайте лишних инициализаций Среда выполнения .NET инициализирует все поля ссылочных типов значениями по умолчанию перед запуском конструктора. В большинстве случаев явная инициализация поля со значением по умолчанию является избыточной, что увеличивает затраты на обслуживание и может привести к снижению производительности (например, при увеличении размера сборки).
CA1806: не игнорируйте результаты метода Создается, но никогда не используется новый объект, либо вызывается метод, который создает и возвращает новую строку, и такая новая строка никогда не используется, либо метод COM или P/Invoke возвращает HRESULT или код ошибки, который никогда не используется.
CA1810: инициализируйте статические поля ссылочного типа встроенными средствами Если тип объявляет явный статический конструктор, JIT-компилятор добавляет проверку к каждому статическому методу и конструктору экземпляра этого типа, чтобы убедиться, что статический конструктор уже был вызван. Проверки статических конструкторов могут привести к снижению производительности.
CA1812: не создавайте внутренние классы без экземпляров Экземпляр типа, определённого на уровне сборки, не создаётся кодом этой сборки.
CA1813: Избегайте незапечатанных атрибутов .NET предоставляет методы для извлечения настраиваемых атрибутов. По умолчанию эти методы осуществляют поиск иерархии наследования атрибутов. Если запечатать атрибут, поиск в иерархии наследования выполняться не будет, в результате чего может повыситься производительность.
CA1814: используйте ступенчатые массивы вместо многомерных Ступенчатый массив — это массив, элементами которого являются массивы. Массивы, которые составляют элементы, могут иметь различные размеры, что позволяет экономить пространство для некоторых наборов данных.
CA1815: Переопределяйте Equals и оператор равенства для типов значений В унаследованной реализации Equals для типов значений используется библиотека отражения и сравнивается содержимое всех полей. Рефлексия требует больших вычислительных затрат, и сравнивать все поля на равенство может быть необязательно. Если предполагается, что пользователи будут сравнивать, сортировать экземпляры или использовать их в качестве ключей хэш-таблиц, тип значения должен реализовывать Equals.
CA1819: свойства не должны возвращать массивы Массивы, возвращаемые свойствами, не защищены от записи, даже если свойство доступно только для чтения. Чтобы защитить массив от изменений, свойство должно возвращать копию массива. Как правило, пользователи не поймут, к каким негативным последствиям для производительности может привести обращение к такому свойству.
CA1820: проверьте наличие пустых строк путем проверки длины строки Сравнивать строки с использованием свойства String.Length или метода String.IsNullOrEmpty значительно быстрее, чем с помощью Equals.
CA1821: удаляйте пустые методы завершения Если возможно, старайтесь не использовать финализаторы, поскольку из-за отслеживания жизненного срока объектов снижается производительность программы. Пустой финализатор влечет дополнительные накладные расходы, не принося никакой пользы.
CA1822: пометить члены как статические Члены, которые не обращаются к данным экземпляра и не вызывают методы экземпляра, могут быть помечены как статические (Shared в Visual Basic). Если пометить методы как статические, компилятор предоставит этим членам невиртуальные места вызова. Это обеспечивает значительное повышение производительности при работе с кодом, для которого важна высокая производительность системы.
CA1823: избегайте наличия неиспользованных закрытых полей Обнаружены закрытые поля, доступ к которым, судя по всему, не предоставляется в сборке.
CA1824: Пометьте сборки атрибутом NeutralResourcesLanguageAttribute Атрибут NeutralResourcesLanguage сообщает Resource Manager о языке, используемом для отображения независящих от языка и региональных параметров ресурсов для сборки. Это повышает производительность поиска для первого ресурса, который вы загружаете, а также может уменьшить рабочее множество.
CA1825: Избегайте выделения массива нулевой длины Инициализация массива нулевой длины приводит к выделению лишней памяти. Вместо этого используйте статический выделенный экземпляр пустого массива, вызвав метод Array.Empty. Выделение памяти является общим для всех вызовов этого метода.
CA1826: используйте свойство вместо метода Linq Enumerable Метод LINQ Enumerable использовался для типа, поддерживающего эквивалентное и более эффективное свойство.
CA1827: Не используйте Count/LongCount, если можно использовать Any Использовался метод Count или LongCount, тогда как более эффективным был бы метод Any.
CA1828: не используйте CountAsync/LongCountAsync при использовании AnyAsync Использовался метод CountAsync или LongCountAsync, тогда как более эффективным был бы метод AnyAsync.
CA1829: используйте свойство Length/Count вместо метода Enumerable.Count Метод LINQ Count использовался для типа, поддерживающего эквивалентное и более эффективное свойство Length или Count.
CA1830: Предпочитайте строго типизированные перегрузки методов Append и Insert на StringBuilder Методы Append и Insert предоставляют перегрузки для нескольких типов, помимо System.String. По возможности рекомендуется использовать строго типизированные перегрузки вместо использования ToString() и перегрузки на основе строк.
CA1831: используйте AsSpan вместо индексаторов на основе диапазона для строки при необходимости При использовании в строке индексатора диапазона и неявного присваивания значения типу ReadOnlySpan<char> метод Substring будет использоваться вместо Slice, который создает копию запрошенной части строки.
CA1832: используйте AsSpan или AsMemory вместо индексаторов на основе диапазона для получения части ReadOnlySpan или ReadOnlyMemory массива При использовании в массиве индексатора диапазона и неявного присваивания значения типу ReadOnlySpan<T> или ReadOnlyMemory<T> метод GetSubArray будет использоваться вместо Slice, который создает копию запрошенной части массива.
CA1833: Используйте AsSpan или AsMemory вместо индексаторов диапазона для получения части массива в виде Span или Memory При использовании в массиве индексатора диапазона и неявного присваивания значения типу Span<T> или Memory<T> метод GetSubArray будет использоваться вместо Slice, который создает копию запрошенной части массива.
CA1834: используйте StringBuilder.Append(char) для одно символьных строк StringBuilder имеет перегрузку Append, принимающую char в качестве параметра. Предпочтительно вызывать перегрузку char для повышения производительности.
CA1835: Предпочитайте перегрузки с использованием 'Memory' для 'ReadAsync' и 'WriteAsync' Stream имеет перегрузку ReadAsync, которая принимает Memory<Byte> в качестве первого аргумента, и перегрузку WriteAsync, принимающую ReadOnlyMemory<Byte> в качестве первого аргумента. Предпочтительно использовать перегрузки, работающие с памятью, так как они эффективнее.
CA1836: используйте IsEmpty вместо Count по возможности Используйте свойство IsEmpty, которое более эффективно, чем Count, Length, Count<TSource>(IEnumerable<TSource>) или LongCount<TSource>(IEnumerable<TSource>), чтобы определить, содержит ли объект какие-либо элементы.
CA1837: используйте Environment.ProcessId вместо Process.GetCurrentProcess().Id Environment.ProcessId проще и быстрее, чем Process.GetCurrentProcess().Id.
CA1838: не используйте параметры StringBuilder для вызовов P/Invoke Маршаллирование StringBuilder всегда создает собственную копию буфера, что приводит к нескольким выделениям для одной операции маршалинга.
CA1839: используйте Environment.ProcessPath вместо Process.GetCurrentProcess().MainModule.FileName Environment.ProcessPath проще и быстрее, чем Process.GetCurrentProcess().MainModule.FileName.
CA1840: используйте Environment.CurrentManagedThreadId вместо Thread.CurrentThread.ManagedThreadId Environment.CurrentManagedThreadId более компактен и эффективен, чем Thread.CurrentThread.ManagedThreadId.
CA1841: предпочитайте словари, содержащие методы Вызов Contains для коллекции Keys или Values зачастую может быть более затратным, чем вызов ContainsKey или ContainsValue для самого словаря.
CA1842: не используйте "WhenAll" с одной задачей Использование WhenAll с одной задачей может привести к потере производительности. Ждать или возвращать задачу.
CA1843: не используйте WaitAll с одной задачей Использование WaitAll с одной задачей может привести к потере производительности. Ожидайте или вместо этого верните задачу.
CA1844: обеспечение переопределения асинхронных методов на основе памяти при создании подкласса Stream Чтобы повысить производительность, переопределите асинхронные методы на основе памяти при создании подкласса Stream. Затем реализуйте методы на основе массивов в контексте методов на основе памяти.
CA1845: Используйте 'string.Concat' на основе Span Более эффективно использовать AsSpan и string.Concat, а не Substring и оператор объединения.
CA1846: предпочитать AsSpan вместо Substring Метод AsSpan является более эффективным, чем Substring. Substring выполняет копирование строк со сложностью O(n), тогда как AsSpan этого не делает и стоимость этого метода константна. AsSpan также не выполняет никаких выделений памяти в куче.
CA1847: используйте символьный литерал при поиске одного символа Используйте String.Contains(char) вместо String.Contains(string) при поиске одного символа.
CA1848: Используйте делегаты LoggerMessage Для повышения производительности используйте делегаты LoggerMessage.
CA1849. Вызов асинхронных методов в методе async В методе, который уже является асинхронным, вызовы других методов должны соответствовать их асинхронным версиям, если они существуют.
CA1850: используйте статический метод HashData вместо ComputeHash Использование статического метода HashData эффективнее создания экземпляра HashAlgorithm и управления им для вызова ComputeHash.
CA1851: Возможно многократное перечисление IEnumerable коллекции Возможен многократный перебор коллекции IEnumerable. Рекомендуется использовать реализацию, которая избегает нескольких перечислений.
CA1852: Сделайте внутренние типы закрытыми Тип, недоступный за пределами своей сборки и не имеющий подтипов в сборке, в которой он содержится, не является закрытым.
CA1853: Ненужный вызов "Dictionary.ContainsKey(key)" Нет необходимости защищать Dictionary.Remove(key) при помощи Dictionary.ContainsKey(key). Dictionary<TKey,TValue>.Remove(TKey) уже проверяет, существует ли ключ и не вызывается, если он не существует.
CA1854: Следует предпочитать метод "IDictionary.TryGetValue(TKey, out TValue)" Предпочитайте "TryGetValue" для доступа к индексатору словаря, защищенному проверкой "ContainsKey". «ContainsKey» и индексатор оба выполняют поиск ключа, поэтому использование «TryGetValue» позволяет избежать дополнительного поиска.
CA1855: используйте Span<T>.Clear() вместо Span<T>.Fill() Эффективнее вызвать Span<T>.Clear(), чем использовать Span<T>.Fill(T) для заполнения элементов диапазона значением по умолчанию.
CA1856: неправильное использование атрибута ConstantExpected Атрибут ConstantExpectedAttribute не применяется правильно к параметру.
CA1857: параметр ожидает константы для оптимальной производительности В параметр, аннотированный с помощью ConstantExpectedAttribute, передан недопустимый аргумент.
CA1858: используйте StartsWith вместо IndexOf Более эффективно String.StartsWith вызывать, чем String.IndexOf вызывать, чтобы проверить, начинается ли строка с заданным префиксом.
CA1859: используйте конкретные типы, если это возможно для повышения производительности Код использует типы интерфейса или абстрактные типы, что приводит к ненужным вызовам интерфейса или виртуальным вызовам.
CA1860: избегайте использования метода расширения "Enumerable.Any()" Более эффективно и ясно использовать Length, Countили IsEmpty (если возможно), чем вызывать Enumerable.Any , чтобы определить, имеет ли тип коллекции какие-либо элементы.
CA1861: избегайте массивов констант в качестве аргументов Массивы констант, передаваемые в качестве аргументов, не используются повторно, что подразумевает затраты на производительность. Рассмотрите возможность вынести их в статические поля только для чтения, чтобы повысить производительность.
CA1862: используйте перегрузки метода StringComparison для сравнения строк без учета регистра. Когда код вызывает ToLower() или ToUpper() для выполнения сравнения строк без учета регистра, выполняется ненужное выделение памяти.
CA1863: используйте составной формат Чтобы уменьшить затраты на форматирование, кэшируйте экземпляр CompositeFormat и используйте его в качестве аргумента для String.Format или StringBuilder.AppendFormat.
CA1864: Следует использовать метод IDictionary.TryAdd(TKey, TValue) И Dictionary<TKey,TValue>.ContainsKey(TKey), и Dictionary<TKey,TValue>.Add выполняют поиск, что является избыточным. Эффективнее вызвать Dictionary<TKey,TValue>.TryAdd, при этом возвращается значение bool, указывающее, было ли значение добавлено. TryAdd не перезаписывает значение ключа, если ключ уже присутствует.
CA1865-CA1867: использование перегрузки char Перегрузка с параметром char обеспечивает более высокую производительность для строки, содержащей один символ.
CA1868: Ненужный вызов "Contains" для множеств И ISet<T>.Add(T), и ICollection<T>.Remove(T) выполняют поиск, поэтому нет необходимости заранее вызывать ICollection<T>.Contains(T). Более эффективно вызывать Add(T) или Remove(T) напрямую, возвращая логическое значение, указывающее, был ли добавлен или удален элемент.
CA1869: кэшируйте и повторно используйте экземпляры JsonSerializerOptions Использование локального экземпляра JsonSerializerOptions сериализации или десериализации может значительно снизить производительность приложения, если код выполняется несколько раз, так как System.Text.Json внутренне кэширует метаданные, связанные с сериализацией, в предоставленный экземпляр.
CA1870: использование кэшированного экземпляра SearchValues Использование кэшированного экземпляра SearchValues<T> более эффективно, чем передача значений в IndexOfAny или ContainsAny напрямую.
CA1871: не передавайте обнуляемую структуру в 'ArgumentNullException.ThrowIfNull' "ArgumentNullException.ThrowIfNull" принимает объект, поэтому передача структуры, допускающего значение NULL, может привести к тому, что значение будет задано в поле.
CA1872: Предпочитайте "Convert.ToHexString" и "Convert.ToHexStringLower" вместо цепочек вызовов на основе "BitConverter.ToString" Используйте Convert.ToHexString или Convert.ToHexStringLower при кодировании байтов в шестнадцатеричное строковое представление. Эти методы более эффективны и требуют меньше выделений памяти, чем использование BitConverter.ToString в сочетании с String.Replace для замены тире и String.ToLower.
CA1873: избегайте потенциально дорогостоящего логгирования При вызове методов ведения журнала их аргументы оцениваются независимо от того, включен ли уровень ведения журнала. Это может привести к выполнению дорогостоящих операций, даже если сообщение журнала не будет записано. Для повышения производительности можно защитить дорогостоящие вызовы ведения журнала с помощью проверки IsEnabled или использования LoggerMessage шаблона.
CA1874: используйте Regex.IsMatch. Regex.IsMatch проще и быстрее, чем Regex.Match(...).Success.
CA1875: используйте Regex.Count. Regex.Count проще и быстрее, чем Regex.Matches(...).Count.
CA1877: используйте перегрузки для Path.Combine или Path.Join. Несколько последовательных Path.Combine или Path.Join операций можно свернуть в один вызов с помощью перегрузок, которые принимают несколько сегментов пути.
CA1878: Следует предпочитать свойства типа ReadOnlySpan полям массива только для чтения Частное статическое поле константного массива можно заменить свойством ReadOnlySpan<T> , чтобы компилятор C# может избежать выделения управляемого массива.