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

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

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

Правило Description
CA1802. Используйте литералы там, где возможно Поле объявляется статичным и доступным только для чтения (Shared и ReadOnly в Visual Basic) и инициализируется со значением, вычисляемым во время компиляции. Поскольку значение, присвоенное конечному полю, вычисляется во время компиляции, замените объявление полем const (Const в Visual Basic), чтобы значение вычислялось не во время выполнения, а во время компиляции.
CA1805: не делайте лишних инициализаций Среда выполнения .NET инициализирует все поля ссылочных типов со значениями по умолчанию перед выполнением конструктора. В большинстве случаев явная инициализация поля со значением по умолчанию является избыточной, что увеличивает затраты на обслуживание и может привести к снижению производительности (например, при увеличении размера сборки).
CA1806: не игнорируйте результаты метода Создается, но никогда не используется новый объект, либо вызывается метод, который создает и возвращает новую строку, и такая новая строка никогда не используется, либо метод COM или P/Invoke возвращает HRESULT или код ошибки, который никогда не используется.
CA1810: инициализируйте статические поля ссылочного типа встроенными средствами Если в типе объявляется явный статический конструктор, компилятор JIT добавляет проверку в каждый статический метод и конструктор экземпляров этого типа, чтобы убедиться, что статический конструктор уже вызывался ранее. Проверки статических конструкторов могут привести к снижению производительности.
CA1812: не создавайте внутренние классы без экземпляров Экземпляр типа уровня сборки не создается кодом в сборке.
CA1813: избегайте распечатанных атрибутов .NET предоставляет методы для извлечения настраиваемых атрибутов. По умолчанию эти методы осуществляют поиск иерархии наследования атрибутов. Если запечатать атрибут, поиск в иерархии наследования выполняться не будет, в результате чего может повыситься производительность.
CA1814: используйте ступенчатые массивы вместо многомерных Массив массивов — это массив, элементы которого сами являются массивами. Массивы, которые составляют элементы, могут иметь различные размеры, что позволяет экономить пространство для некоторых наборов данных.
CA1815: следует переопределять равенства и равенства операторов в типах значений В унаследованной реализации Equals для типов значений используется библиотека отражения и сравнивается содержимое всех полей. Отражение является процессом, требующим с точки зрения вычислений больших затрат, и сравнение каждого поля на равенство может быть лишним. Если предполагается, что пользователи будут сравнивать, сортировать экземпляры или использовать их в качестве ключей хэш-таблиц, тип значения должен реализовывать Equals.
CA1819: свойства не должны возвращать массивы Массивы, возвращаемые свойствами, не защищены от записи, даже если свойство доступно только для чтения. Чтобы защитить массив от изменений, свойство должно возвращать копию массива. Как правило, пользователи не понимают требований к производительности при вызове такого свойства.
CA1820: проверьте наличие пустых строк путем проверки длины строки Сравнивать строки с использованием свойства String.Length или метода String.IsNullOrEmpty значительно быстрее, чем с помощью Equals.
CA1821: удаляйте пустые методы завершения Если возможно, старайтесь не использовать финализаторы, поскольку из-за отслеживания жизненного срока объектов снижается производительность программы. Пустой метод завершения приводит к дополнительной нагрузке без каких бы то ни было преимуществ.
CA1822: помечайте члены как статические Элементы, не обращающиеся к данным экземпляра и не вызывающие методы экземпляра, можно помечать как статические (общие в Visual Basic). Если пометить методы как статические, компилятор предоставит этим членам невиртуальные места вызова. Это обеспечивает значительное повышение производительности при работе с кодом, для которого важна высокая производительность системы.
CA1823: избегайте наличия неиспользованных закрытых полей Обнаружены закрытые поля, доступ к которым, судя по всему, не предоставляется в сборке.
CA1824: следует помечать сборки атрибутом NeutralResourcesLanguageAttribute Атрибут NeutralResourcesLanguage сообщает Resource Manager о языке, используемом для отображения независящих от языка и региональных параметров ресурсов для сборки. При этом повышается эффективность поиска первого загружаемого ресурса и может сократиться рабочее множество.
CA1825: избегайте выделения массива нулевой длины Инициализация массива нулевой длины приводит к выделению лишней памяти. Вместо этого используйте статический выделенный экземпляр пустого массива, вызвав метод Array.Empty. Выделение памяти является общим для всех вызовов этого метода.
CA1826: используйте свойство вместо метода Linq Enumerable Метод LINQ Enumerable использовался для типа, поддерживающего эквивалентное и более эффективное свойство.
CA1827: не используйте Count/LongCount, если можно использовать Любой. Использовался метод Count или LongCount, тогда как более эффективным был бы метод Any.
CA1828: не используйте CountAsync/LongCountAsync при использовании AnyAsync Использовался метод CountAsync или LongCountAsync, тогда как более эффективным был бы метод AnyAsync.
CA1829: используйте свойство Length/Count вместо метода Enumerable.Count Метод LINQ Count использовался для типа, поддерживающего эквивалентное и более эффективное свойство Length или Count.
CA1830: предпочитайте строго типизированные перегрузки методов Добавления и вставки в 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<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 на основе диапазона Более эффективно использовать 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: используйте диапазон<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: не передайте структуру, допускаемую значение NULL, в "ArgumentNullException.ThrowIfNull" "ArgumentNullException.ThrowIfNull" принимает объект, поэтому передача структуры, допускающего значение NULL, может привести к тому, что значение будет задано в поле.
CA1872: предпочитайте "Convert.ToHexString" и "Convert.ToHexStringLower" по цепочкам вызовов на основе BitConverter.ToString. Используйте Convert.ToHexString или Convert.ToHexStringLower когда кодирование байтов в шестнадцатеричное строковое представление. Эти методы более эффективны и удобны для выделения, чем используются BitConverter.ToString в сочетании с String.Replace заменой дефисов и String.ToLower.