Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/core/whats-new/dotnet-8/runtime.md
Original file line number Diff line number Diff line change
Expand Up @@ -513,7 +513,8 @@ IDataView predictions = model.Transform(split.TestSet);
}
```

- Methods like <xref:System.MemoryExtensions.IndexOfAny%2A?displayProperty=nameWithType> look for the first occurrence of *any value in the passed collection*. The new <xref:System.Buffers.SearchValues%601?displayProperty=fullName> type is designed to be passed to such methods. Correspondingly, .NET 8 adds new overloads of methods like <xref:System.MemoryExtensions.IndexOfAny%2A?displayProperty=nameWithType> that accept an instance of the new type. When you create an instance of <xref:System.Buffers.SearchValues%601>, all the data that's necessary to optimize subsequent searches is derived *at that time*, meaning the work is done up front.
- Methods like <xref:System.MemoryExtensions.IndexOfAny%2A?displayProperty=nameWithType> look for the first occurrence of *any value in the passed collection*. The new <xref:System.Buffers.SearchValues%601?displayProperty=fullName> type is designed to be passed to such methods. Correspondingly, .NET 8 adds new overloads of methods like <xref:System.MemoryExtensions.IndexOfAny%2A?displayProperty=nameWithType> that accept an instance of the new type. When you create an instance of <xref:System.Buffers.SearchValues%601>, all the data that's necessary to optimize subsequent searches is derived *at that time*, meaning the work is done up front.
For guidance on using `SearchValues<T>` for efficient multi-value string comparisons, see [Efficient multi-value string comparisons](../../standard/base-types/string-comparison.md#efficient-multi-value-string-comparisons).
- The new <xref:System.Text.CompositeFormat?displayProperty=fullName> type is useful for optimizing format strings that aren't known at compile time (for example, if the format string is loaded from a resource file). A little extra time is spent up front to do work such as parsing the string, but it saves the work from being done on each use.

```csharp
Expand Down
32 changes: 32 additions & 0 deletions docs/standard/base-types/string-comparison-net-5-plus.md
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,38 @@ ReadOnlySpan<char> span = s.AsSpan();
if (span.StartsWith("Hello", StringComparison.Ordinal)) { /* do something */ } // ordinal comparison
```

## Efficient multi-value string comparisons

When comparing a string against a fixed set of known values repeatedly, consider using `SearchValues<T>` instead of chained comparisons or LINQ-based approaches.
`SearchValues<T>` can precompute internal lookup structures and optimize the comparison logic based on the provided values.

### Recommended usage

Create and cache the `SearchValues<string>` instance once, then reuse it for comparisons:

```cs
using System.Buffers;

private static readonly SearchValues<string> Commands = SearchValues.Create(new[] { "start", "run", "go" }, StringComparison.OrdinalIgnoreCase);

if (Commands.Contains(command))
{
/* do something */
}
```
### Avoid repeated creation
Avoid creating `SearchValues` instances inside hot paths or per comparison, as the creation step can be relatively expensive:

```cs
// Avoid this pattern
if (SearchValues.Create(new[] { "start", "run", "go" }, StringComparison.OrdinalIgnoreCase).Contains(command))
{
/* do something */
}
```
Caching and reusing the instance ensures optimal performance.


## See also

- [Globalization breaking changes in .NET 5](../../core/compatibility/5.0.md#globalization)
Expand Down
Loading