Правила производительности
Правила производительности поддерживают высокоэффективные библиотеки и приложения.
В этом разделе
Правило | 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. |
Совместная работа с нами на GitHub
Источник этого содержимого можно найти на GitHub, где также можно создавать и просматривать проблемы и запросы на вытягивание. Дополнительные сведения см. в нашем руководстве для участников.