Ich habe einen Zeichenfolgenpuffer von ca. 2000 Zeichen und muss den Puffer überprüfen, wenn er eine bestimmte Zeichenfolge enthält.
Führt die Prüfung in einer ASP.NET 2.0-Webanwendung für jede Webanforderung durch.
Weiß jemand, ob die String.Contains-Methode eine bessere Leistung als die String.IndexOf-Methode aufweist ?
// 2000 characters in s1, search token in s2
string s1 = "Many characters. The quick brown fox jumps over the lazy dog";
string s2 = "fox";
bool b;
b = s1.Contains(s2);
int i;
i = s1.IndexOf(s2);
Antworten:
Contains
AnrufeIndexOf
:Welche Aufrufe
CompareInfo.IndexOf
, welche letztendlich eine CLR-Implementierung verwenden.Wenn Sie sehen möchten, wie Zeichenfolgen in der CLR verglichen werden, wird dies angezeigt (suchen Sie nach CaseInsensitiveCompHelper ).
IndexOf(string)
hat keine Optionen undContains()
verwendet einen Ordnungsvergleich (einen byteweisen Vergleich, anstatt zu versuchen, einen intelligenten Vergleich durchzuführen, z. B. e mit é).So
IndexOf
wird geringfügig schneller (in der Theorie) alsIndexOf
gerade auf eine String - Suche geht mit FindNLSString von kernel32.dll (die Kraft des Reflektors!).Aktualisiert für .NET 4.0 - IndexOf verwendet keinen Ordnungsvergleich mehr und kann daher schneller sein. Siehe Kommentar unten.
quelle
IndexOf()
verwendet tatsächlichStringComparison.CurrentCulture
undContains()
verwendet,StringComparison.Ordinal
was schneller sein wird. Aber die Geschwindigkeitsunterschiede, über die wir sprechen, sind wirklich winzig - der Punkt ist, dass einer den anderen aufruft und Contains besser lesbar ist, wenn Sie den Index nicht benötigen. Mit anderen Worten, mach dir keine Sorgen.Wahrscheinlich wird es überhaupt keine Rolle spielen. Lesen Sie diesen Beitrag über Coding Horror;): http://www.codinghorror.com/blog/archives/001218.html
quelle
Contains (s2) ist viele Male (auf meinem Computer 10 Mal) schneller als IndexOf (s2), da Contains StringComparison.Ordinal verwendet, das schneller ist als die kultursensitive Suche, die IndexOf standardmäßig durchführt (dies kann sich jedoch in .net 4.0 ändern : http: //davesbox.com/archive/2008/11/12/breaking-changes-to-the-string-class.aspx ).
Enthält in meinen Tests genau die gleiche Leistung wie IndexOf (s2, StringComparison.Ordinal)> = 0, ist jedoch kürzer und macht Ihre Absicht klar.
quelle
Ich führe einen echten Fall durch (im Gegensatz zu einem synthetischen Benchmark)
gegen
Es ist ein wichtiger Teil meines Systems und wird 131.953 Mal ausgeführt (danke DotTrace).
Wie schockierend die Überraschung auch sein mag , das Ergebnis ist das Gegenteil von dem, was erwartet wurde
: - /
Net Framework 4.0 (aktualisiert am 13-02-2012)
quelle
INT
ist viel größer alsBOOL
undIndexOf>=0
verursachen einen weiteren SchrittWenn Sie Reflector verwenden, können Sie sehen, dass Contains mit IndexOf implementiert wird. Hier ist die Implementierung.
Contains ist also wahrscheinlich etwas langsamer als der direkte Aufruf von IndexOf, aber ich bezweifle, dass dies für die tatsächliche Leistung von Bedeutung sein wird.
quelle
Wenn Sie Ihren Code wirklich mikrooptimieren möchten, ist Benchmarking immer der beste Ansatz.
Das .net-Framework verfügt über eine hervorragende Stoppuhr-Implementierung - System.Diagnostics.Stopwatch
quelle
Aus einer kleinen Lektüre geht hervor, dass die String.Contains-Methode unter der Haube einfach String.IndexOf aufruft. Der Unterschied besteht darin, dass String.Contains einen Booleschen Wert zurückgibt, während String.IndexOf eine Ganzzahl mit (-1) zurückgibt, die angibt, dass der Teilstring nicht gefunden wurde.
Ich würde vorschlagen, einen kleinen Test mit etwa 100.000 Iterationen zu schreiben und sich selbst davon zu überzeugen. Wenn ich raten würde, würde ich sagen, dass IndexOf vielleicht etwas schneller ist, aber wie gesagt, es ist nur eine Vermutung.
Jeff Atwood hat einen guten Artikel über Streicher in seinem Blog . Es geht mehr um Verkettung, kann aber dennoch hilfreich sein.
quelle
Gerade als Update habe ich einige Tests durchgeführt und vorausgesetzt, Ihre Eingabezeichenfolge ist ziemlich groß, dann ist parallel Regex die schnellste C # -Methode, die ich gefunden habe (vorausgesetzt, Sie haben mehr als einen Kern, wie ich mir vorstelle).
Zum Beispiel die Gesamtzahl der Übereinstimmungen abrufen -
Hoffe das hilft!
quelle
Verwenden Sie eine Benchmark-Bibliothek, wie diesen jüngsten Streifzug von Jon Skeet , um sie zu messen.
Vorbehalt Emptor
Wie bei allen (Mikro-) Leistungsfragen hängt dies von den von Ihnen verwendeten Softwareversionen, den Details der überprüften Daten und dem Code ab, der den Anruf umgibt.
Wie bei allen (Mikro-) Leistungsfragen muss der erste Schritt darin bestehen, eine laufende Version zu erhalten, die leicht zu warten ist. Dann können Benchmarking, Profiling und Tuning auf die gemessenen Engpässe angewendet werden, anstatt zu raten.
quelle
Für alle, die dies noch lesen, wird indexOf () auf den meisten Unternehmenssystemen wahrscheinlich eine bessere Leistung erzielen, da enthält () nicht mit dem IE kompatibel ist!
quelle