Die Anzahl eines Zeichens in einem String ermitteln

Heute wurde ich mal wieder mit einem kleinen Problemchen konfrontiert. Und zwar musst ich die Anzahl eines bestimmten Zeichens innerhalb eines Strings ermitteln. Kein Problem Dachte ich mir und fing an.
Während ich die Funktion schrieb, kam mir ein Gedanke. "Wie sieht es denn mit der Performance aus?"


Hmm. Eine gute Frage...
Rasch eine Neue Projektmappe aufgemacht und angefangen das zu Testen.

Meine erste Ansatz war jedes Zeichen des Strings durchzugehen und bei einer Übereinstimmung mit dem gesuchten Zeichen eine Zählervariable zu inkrementieren.

public static int FindCharWithForEach(string source, char searchFor)
{
    var counter = 0;
 
    foreach (char c in source)
    {
        if (c == searchFor) counter++;
    }
 
    return counter;
}

Als Testszenario hab ich mir einen Verzeichnispfad (C:\Windows\System32\drivers\etc) geschnappt und wollte wissen wie viele '\' darin enthalten sind.
Die Funktion lief ohne Probleme und gab mir nach 00:00:00.0003581 das korrekte Ergebnis von 4 zurück.

Mein zweiter Ansatz war, das ganze Mit LINQ umzusetzen.

public static int FindCharWithLinq(string source, char searchFor)
{
    return source.Count(f => f == searchFor);
}

Auch diese Variante lief ohne Probleme. Nur mit einer Zeit von 00:00:00.0046630 hätte ich nicht gerechnet.

Ok. Dann suchen wir mal weiter.
Mein nächste Gedanke war den String einfach zu Splitten und die Anzahl der Elemente im Array (-1) zu zählen.

public static int FindCharWithSplit(string source, char searchFor)
{
    return source.Split(searchFor).Length - 1;
}

Auch diese Lösung funktionierte. Allerdings war ich ein wenig überrascht, das diese Variante mit 00:00:00.0004546 doch deutlich schnellsten als die LINQ Version war.

Nachdem ich diese Resultate gesehen hatte, dachte ich mir, das ich den Test etwas Anspruchsvoller zu gestallten und duplizierte den Pfad ein paar mal um einen möglichst langen String zu erzeugen.

string value = "";
for(int i = 0 ; i < 10; i++)
    value = value + @"C:\Windows\System32\drivers\etc";

Beim Test war das erwartete Ergebnis 40, da ich den Text einfach 10 mal hintereinander kopiert habe.

LINQ:

40 hits in 00:00:00.0055382

Split:

40 hits in 00:00:00.0004590

Count:

40 hits in 00:00:00.0007574

Nach dem Ergebnis dacht ich mir eine kleine Serie draus zu bauen und habe noch Tests für Text x 100, x 1000, x 10000, x 100000 und x 1000000 laufen lassen.
Um LINQ noch kleine Zusatz Chance zu geben, habe ich noch PLINQ mit dazu genommen. Der PC auf dem die Tests laufen ist ein einfacher Dual Core mit einem Intel Core2Duo P9700 mit 2x2.80GHz.

 

10

100

1.000

LINQ

40 hits in 00:00:00.0055382

400 hits in 00:00:00.0089991

4000 hits in 00:00:00.0724733

Split

40 hits in 00:00:00.0004590

400 hits in 00:00:00.0004476

4000 hits in 00:00:00.0008498

Count

40 hits in 00:00:00.0007574

400 hits in 00:00:00.0024534

4000 hits in 00:00:00.0204854

PLINQ

40 hits in 00:00:00.6701543

400 hits in 00:00:00.2043689

4000 hits in 00:00:00.2359259

10.000

100.000

1.000.000

LINQ

40000 hits in 00:00:00.5656169

400000 hits in 00:00:05.5925695

4000000 hits in 00:00:56.1154690

Split

40000 hits in 00:00:00.0045024

400000 hits in 00:00:00.0489870

4000000 hits in 00:00:00.9762967

Count

40000 hits in 00:00:01.8509596

400000 hits in 00:00:03.4958518

4000000 hits in 00:00:38.0938921

PLINQ

40000 hits in 00:00:00.6517095

400000 hits in 00:00:04.8506172

4000000 hits in 00:00:45.4006163


Ich glaub zu den Ergebnissen bracht man nicht mehr viel sagen, da Diese sehr eindeutig sind.
LINQ ist kein Allheilmittel und die einfachsten Wege sind nicht unbedingt die Besten.

Ich habe nun meinen Favoriten. :)

For so long,
CJ


In this article



Most Recent

Hintergrundbeleuchtung für Laptops, die als Server laufen, ausschalten
Continue reading...

More posts

Sha Hash für Strings mit C#
Sha Hash für Strings mit C#

Vor einiger Zeit hab ich bereits gezeigt wie man SHA Hashes eines Strings mit Java generiert. Nun möchte ich aber der .Net Gemeinde nichts...

Entferne überflüssige Whitespaces mit C#
Entferne überflüssige Whitespaces mit C#

Heute wurde ich gefragt, ob und wie es möglich sein, mit Hilfe von C# alle doppelten bzw. überflüssigen Whitespaces in einem Text zu entfernen. Mit...

SQL-Server: If Exists Update Else Insert
SQL-Server: If Exists Update Else Insert

Eine eine ziemlich häufige und immer wiederkehrende Situation, bei der Entwicklung mit Datenbanken ist es, das man Daten aktualisieren, bzw wenn...

Dateien mit C# und GZip packen und entpacken
Dateien mit C# und GZip packen und entpacken

Wer öfters mit Dateien arbeitet wird immer wieder mit komprimierten Dateien konfrontiert. Mal bekommt man sie und manchmal muss man solche Dateien...