Neu in .NET 9.0 [21]: Ohne Speicherallokationen nach Zeichenketten suchen

Die Typen HashSet<T> und Dictionary<T, T> erlauben die Suche nach Daten mit einem ReadOnlySpan<T>.

vorlesen Druckansicht

(Bild: Pincasso/Shutterstock.com)

Lesezeit: 1 Min.
Von
  • Dr. Holger Schwichtenberg

In .NET 9.0 bieten die Typen HashSet<T> und Dictionary<T, T> eine neue Möglichkeit, nach Elementen mit einem ReadOnlySpan<T> zu suchen. Das vermeidet bei der Suche nach Zeichenketten viele Speicherallokationen.

Der Dotnet-Doktor – Holger Schwichtenberg
Der Dotnet-Doktor – Holger Schwichtenberg

Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.

Beispiel: In einer durch Semikolon getrennten Namensmenge soll nach Namen gesucht werden.

Videos by heise

Gegeben ist

HashSet<string> suchwoerter = 
  new HashSet<string>() { "MĂĽller", "Meier", "Schulze" };
string[] datenbasis = """
 Müller;Schwichtenberg;Stropek;Krämer
 Huber;Meier;Loje
 Schulze;Wenz;Schmaranz
 ...
 """.Split("\n");

Die bisherige Implementierung vor .NET 9.0 könnte folgendermaßen aussehen:

foreach (string line in datenbasis) 
  {
   foreach (string n in line.Split(';')) // String-Allokation
   {
    if (suchwoerter.Contains(n)) fundstellen1++;
   }
  }
  Console.WriteLine(fundstellen1);

Seit .NET 9.0 kann man für die Suchwörter mit Aufruf der Methode GetAlternateLookup() einen sogenannten "Lookup" erschaffen und anschließend mit einem ReadOnlySpan<char> in dem HashSet<T> suchen:

[code]HashSet<T>[/code] suchen:
HashSet<string>.AlternateLookup<ReadOnlySpan<char>> suchwoerter2 = 
  suchwoerter.GetAlternateLookup<ReadOnlySpan<char>>();
 
int fundstellen2 = 0;
foreach (string line in datenbasis)
{
 ReadOnlySpan<char> lineSpan = line.AsSpan(); // ohne Allokation
 foreach (Range range in lineSpan.Split(';'))
 {
  ReadOnlySpan<char> nameSpan = lineSpan[range]; // ohne Allokation
  if (suchwoerter2.Contains(nameSpan)) fundstellen2++; 
 }
}
Console.WriteLine(fundstellen2);

(rme)