Skip to content

Commit

Permalink
Merge pull request #37056 from MihaZupan/ca1870
Browse files Browse the repository at this point in the history
Add documentation for CA1870
  • Loading branch information
MihaZupan authored Sep 13, 2023
2 parents 6551282 + a16d883 commit 78968f0
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 0 deletions.
100 changes: 100 additions & 0 deletions docs/fundamentals/code-analysis/quality-rules/ca1870.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: "CA1870: Use a cached 'SearchValues' instance"
description: "Learn about code analyzer rule CA1870 - Use a cached 'SearchValues' instance"
ms.date: 09/12/2023
ms.topic: reference
f1_keywords:
- CA1870
- UseSearchValuesAnalyzer
helpviewer_keywords:
- CA1870
dev_langs:
- CSharp
author: MihaZupan
ms.author: mizupan
---

# CA1870: Use a cached 'SearchValues' instance

| Property | Value |
|-------------------------------------|----------------------------------------|
| **Rule ID** | CA1870 |
| **Title** | Use a cached 'SearchValues' instance |
| **Category** | [Performance](performance-warnings.md) |
| **Fix is breaking or non-breaking** | Non-breaking |
| **Enabled by default in .NET 8** | Yes |

## Cause

An `IndexOfAny` or `ContainsAny` method is called with many constant values in a way that can benefit from using <xref:System.Buffers.SearchValues> instead.

The rule doesn't flag calls that use up to five values, as those already use an optimal implementation.

## Rule description

Using a cached <xref:System.Buffers.SearchValues%601> instance is more efficient than passing values to `IndexOfAny` or `ContainsAny` directly.

## How to fix violations

Create and cache a <xref:System.Buffers.SearchValues%601> instance in a `static readonly` field, then pass that instance to the `IndexOfAny` or `ContainsAny` call instead.

A code fixer that performs this transformation is available.

## Example

The following code snippet shows two violations of CA1870:

```csharp
static readonly char[] MyValues = new[] { 'a', 'b', 'c', 'x', 'y', 'z' };

static int IndexOfMyValues(ReadOnlySpan<char> text)
{
return text.IndexOfAny(MyValues);
}

static bool ContainsOnlyMyValues(ReadOnlySpan<char> text)
{
return !text.ContainsAnyExcept("abcxyz");
}
```

The following code snippet fixes the violations:

```csharp
private static readonly SearchValues<char> s_myValues = SearchValues.Create("abcxyz");

static int IndexOfMyValues(ReadOnlySpan<char> text)
{
return text.IndexOfAny(s_myValues);
}

static bool ContainsOnlyMyValues(ReadOnlySpan<char> text)
{
return !text.ContainsAnyExcept(s_myValues);
}
```

If there are multiple calls to `IndexOfAny` with the same set of values, `s_myValues` should be reused.

## When to suppress warnings

It's safe to suppress this warning if performance isn't a concern.

## Suppress a warning

If you just want to suppress a single violation, add preprocessor directives to your source file to disable and then re-enable the rule.

```csharp
#pragma warning disable CA1870
// The code that's violating the rule is on this line.
#pragma warning restore CA1870
```

To disable the rule for a file, folder, or project, set its severity to `none` in the [configuration file](../configuration-files.md).

```ini
[*.{cs,vb}]
dotnet_diagnostic.CA1870.severity = none
```

For more information, see [How to suppress code analysis warnings](../suppress-warnings.md).
1 change: 1 addition & 0 deletions docs/fundamentals/code-analysis/quality-rules/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ The following table lists code quality analysis rules.
> | [CA1865-CA1867: Use char overload](ca1865-ca1867.md) | The char overload is a better performing overload for a string with a single char. |
> | [CA1868: Unnecessary call to 'Contains' for sets](ca1868.md) | Both <xref:System.Collections.Generic.ISet%601.Add(%600)?displayProperty=nameWithType> and <xref:System.Collections.Generic.ICollection%601.Remove(%600)?displayProperty=nameWithType> perform a lookup, which makes it redundant to call <xref:System.Collections.Generic.ICollection%601.Contains(%600)?displayProperty=nameWithType> beforehand. It's more efficient to call <xref:System.Collections.Generic.ISet%601.Add(%600)> or <xref:System.Collections.Generic.ICollection%601.Remove(%600)> directly, which returns a Boolean value indicating whether the item was added or removed. |
> | [CA1869: Cache and reuse 'JsonSerializerOptions' instances](ca1869.md) | Using a local instance of <xref:System.Text.Json.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](ca1870.md) | Using a cached <xref:System.Buffers.SearchValues%601> instance is more efficient than passing values to 'IndexOfAny' or 'ContainsAny' directly. |
> | [CA2000: Dispose objects before losing scope](ca2000.md) | Because an exceptional event might occur that will prevent the finalizer of an object from running, the object should be explicitly disposed before all references to it are out of scope. |
> | [CA2002: Do not lock on objects with weak identity](ca2002.md) |An object is said to have a weak identity when it can be directly accessed across application domain boundaries. A thread that tries to acquire a lock on an object that has a weak identity can be blocked by a second thread in a different application domain that has a lock on the same object. |
> | [CA2007: Do not directly await a Task](ca2007.md) | An asynchronous method [awaits](../../../csharp/language-reference/operators/await.md) a <xref:System.Threading.Tasks.Task> directly. When an asynchronous method awaits a <xref:System.Threading.Tasks.Task> directly, continuation occurs in the same thread that created the task. This behavior can be costly in terms of performance and can result in a deadlock on the UI thread. Consider calling <xref:System.Threading.Tasks.Task.ConfigureAwait(System.Boolean)?displayProperty=nameWithType> to signal your intention for continuation. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,4 @@ Performance rules support high-performance libraries and applications.
| [CA1865-CA1867: Use char overload](ca1865-ca1867.md) | The char overload is a better performing overload for a string with a single char. |
| [CA1868: Unnecessary call to 'Contains' for sets](ca1868.md) | Both <xref:System.Collections.Generic.ISet%601.Add(%600)?displayProperty=nameWithType> and <xref:System.Collections.Generic.ICollection%601.Remove(%600)?displayProperty=nameWithType> perform a lookup, which makes it redundant to call <xref:System.Collections.Generic.ICollection%601.Contains(%600)?displayProperty=nameWithType> beforehand. It's more efficient to call <xref:System.Collections.Generic.ISet%601.Add(%600)> or <xref:System.Collections.Generic.ICollection%601.Remove(%600)> directly, which returns a Boolean value indicating whether the item was added or removed. |
| [CA1869: Cache and reuse 'JsonSerializerOptions' instances](ca1869.md) | Using a local instance of <xref:System.Text.Json.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](ca1870.md) | Using a cached <xref:System.Buffers.SearchValues%601> instance is more efficient than passing values to 'IndexOfAny' or 'ContainsAny' directly. |
2 changes: 2 additions & 0 deletions docs/navigate/tools-diagnostics/toc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -812,6 +812,8 @@ items:
href: ../../fundamentals/code-analysis/quality-rules/ca1868.md
- name: CA1869
href: ../../fundamentals/code-analysis/quality-rules/ca1869.md
- name: CA1870
href: ../../fundamentals/code-analysis/quality-rules/ca1870.md
- name: SingleFile rules
items:
- name: Overview
Expand Down

0 comments on commit 78968f0

Please sign in to comment.