Zurück zur Startseite

SearchValues und FrozenCollections in .NET 8 für Optimierung

Der Artikel zerlegt SearchValues und FrozenCollections in .NET 8 für die Beschleunigung der Suche in Hot Paths. Benchmarks werden bereitgestellt (13x bei Strings, 2x bei Dictionaries) und Code-Beispiele. Empfehlungen für den Einsatz in read-heavy Szenarien.

13x Suchbeschleunigung in .NET 8 mit SearchValues
Advertisement 728x90

.NET 8 Suchoptimierung: SearchValues und FrozenCollections für Hot Paths

.NET 8 führt SearchValues<T> sowie Sammlungen wie FrozenSet<T>/FrozenDictionary<TKey, TValue> ein, die den Overhead in Hot Paths drastisch reduzieren. Diese Strukturen übernehmen die schwere Arbeit bei der Erstellung und ermöglichen Lookups in konstanter Zeit ohne wiederholte Analysen. Sie eignen sich ideal für Anwendungen mit hohem Durchsatz, die Millionen von Operationen verarbeiten.

Charaktersuche mit SearchValues beschleunigen

Die Standardmethode string.IndexOfAny analysiert das Zeichenspektrum bei jedem Aufruf neu und verursacht so Overhead in Schleifen. SearchValues<char> wird einmal erstellt und cached die optimale Suchstrategie.

Bei der Initialisierung führt .NET durch:

Google AdInline article slot
  • Analyse des Eingabesets (einzelnes Zeichen, Bereich oder Mehrzeichen).
  • Algorithmusauswahl mit SIMD-Unterstützung (AVX2, SSE2).
  • Aufbau von Datenstrukturen (Bitmasken, Hash-Tabellen).
SearchValues<char> separators = SearchValues.Create(".,;!?");
ReadOnlySpan<char> input = "Hello, world!";
int index = input.IndexOfAny(separators);

Suchstrategien variieren je nach Daten:

  • Einzelnes Zeichen — vektorisierte Prüfung.
  • Bereich (0-9A-Z) — O(1) Bitmaske.
  • Kleines Set (≤4 Zeichen) — SIMD.
  • Großes Set — optimierte Hash-Tabelle.

Benchmarks zeigen enorme Gewinne:

| Szenario | IndexOfAny | SearchValues | Beschleunigung |

Google AdInline article slot

|----------|------------|--------------|----------------|

| Kurzer String | ~5 ns | ~5 ns | 1x |

| Langer String (2000 Zeichen) | ~52 ns | ~4 ns | ~13x |

Google AdInline article slot

Die größten Vorteile ergeben sich bei Strings über 100 Zeichen, da die wiederholte Analyse entfällt.

FrozenCollections: Unveränderliche Hash-Tabellen

HashSet<T> und Dictionary<TKey, TValue> haben Mutationsoverhead wie Rehashing und Grenzprüfungen. FrozenSet<T> und FrozenDictionary<TKey, TValue> sind für read-only Szenarien optimiert.

Bei der Erstellung:

  • Schlüsselanalyse für eine perfekte Hash-Funktion ohne Kollisionen.
  • Cache-freundliche Datenanordnung.
  • Entfernte Laufzeit-Immutable-Checks.

Kleine Sammlungen nutzen Bitmasken statt Hashing.

var dict = Enumerable.Range(0, 100000)
    .ToFrozenDictionary(x => x, x => $"Wert {{x}}");

if (dict.TryGetValue(42, out string? value))
{
    Console.WriteLine(value);
}

Benchmarks (100.000 Elemente):

| Operation | Dictionary | HashSet | FrozenDictionary | FrozenSet |

|-----------|------------|---------|------------------|-----------|

| TryGetValue/Contains | 3,78 ns | 4,47 ns | 1,87 ns | 3,37 ns |

FrozenDictionary ist doppelt so schnell wie ein Standard-Dictionary.

Praxisbeispiele

SearchValues:

  • Millionen Lookups gegen feste Sets.
  • Log-Parsing, Tokenisierung, Validierung.
  • Lange Strings (>100 Zeichen).

FrozenCollections:

  • Statische Konfigs beim Startup.
  • Lookup-Tabellen (Fehlercodes, Status).
  • Read-lastige Workloads mit Tausenden Lookups.

Vermeiden Sie sie bei häufigen Mutationen oder seltenen Aufrufen – die Erstellungskosten überwiegen.

Praktische Umsetzung

Auf App-Ebene cachen:

public static class AppCache
{
    public static readonly SearchValues<char> UrlSafeChars = 
        SearchValues.Create("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~");
    
    public static readonly FrozenSet<string> ValidCurrencies = 
        new[] { "USD", "EUR", "GBP", "JPY", "CNY" }.ToFrozenSet();
}

Validierungsbeispiele:

  • E-Mail: SearchValues<char> invalidEmailChars = SearchValues.Create("()<>[]:;@\\,?\"");
  • TLD: FrozenSet<string> validTlds = LoadTldsFromConfig().ToFrozenSet();

Immer mit BenchmarkDotNet profilieren – der Nutzen hängt vom Operationsvolumen ab.

Wichtige Erkenntnisse

  • SearchValues beschleunigt Suchen um das 13-Fache bei langen Strings durch einmalige Optimierung.
  • FrozenDictionary verdoppelt die TryGetValue-Performance im Vergleich zu Dictionary.
  • Beide glänzen mit unveränderlichen Sets in Hot Paths.
  • Zuerst profilieren: Nutzlos bei seltenen Aufrufen.
  • SIMD und perfektes Hashing für Erfolge bei Mid-/Senior-Entwicklern nutzen.

— Editorial Team

Advertisement 728x90

Weiterlesen