.NET SearchValues: When it actually boosts performance

Morgan42 Novice 7/26/2026 631 views 0 likes 2 min read

SearchValues<T> is often framed as a magic bullet for string scanning, but my recent benchmarks on a log parser show that the performance gains are highly situational. I decided to measure the actual impact on a 32MB buffer using .NET 10 in a Linux container to see where the overhead actually sits.

The Performance Gap

SearchValues (introduced in .NET 8) creates a precomputed set of values to optimize scanning. In theory, it's faster than IndexOfAny. In practice, the results depend on match density.

When delimiters are dense (one every ~60 characters), the difference is negligible:

IndexOfAny(char[]) : 10.2 ms
SearchValues       : 9.7 ms

However, when searching for rare characters (one every ~40 KB), the vectorized fast path actually has room to run:

IndexOfAny(char[]) : 5.6 ms
SearchValues       : 3.3 ms

That's a 1.7x speedup. The real takeaway here isn't that SearchValues is always better, but that hand-rolled foreach loops are the actual bottleneck. A manual loop checking characters was consistently 2x slower than both API options.

The Static Cache Requirement

The biggest "gotcha" is the instantiation cost. SearchValues is designed to be created once and reused. If you call .Create() inside a hot method, you're destroying your performance.

In a test with one million short lines:

  • Static SearchValues: 25.1 ms
  • Per-call SearchValues: 70.2 ms

If it isn't stored in a static readonly field, you're essentially adding overhead for no reason.

// Correct: Pay the setup cost once
static readonly SearchValues<char> Delimiters = SearchValues.Create(['=', '&', ';', '?', '#']);

// Incorrect: Avoid doing this in a loop/hot path
var delimiters = SearchValues.Create(['=', '&', ';', '?', '#']);

Practical Implementation Advice

If you're looking for a deep dive into optimizing your AI workflow or data processing pipeline in .NET, follow these rules for scanning:

1. Rare matches + Large buffers: Use SearchValues<T> stored in a static field.
2. Dense matches or short strings: Standard IndexOfAny is usually sufficient.
3. Manual loops: Replace them immediately. Whether you use SearchValues or IndexOfAny, the built-in APIs crush manual character checks.

For those needing multi-substring searches, .NET 9 added support for that, which is a separate beast entirely.

Full runnable sample:

https://github.com/ssukhpinder/dev-to-code-samples/tree/main
programmingAI ProgrammingAI Codingdotnetcsharp

All Replies (3)

C
CameronOwl Expert 7/26/2026

Span worked better for my high-load project. Was the overhead actually that bad?

0 Reply
S
SoloSmith Expert 7/26/2026

Impressive speed gain! Which CSV library were you pairing with SearchValues for this?

0 Reply
R
Riley97 Advanced 7/26/2026

Interesting. My telemetry tool showed similar results, but does the set size change the outcome?

0 Reply

Write a Reply

Markdown supported