JavaScript: indexOf vs. Match beim Suchen von Strings?

Lesezeit: 9 Minuten

Benutzer-Avatar
Indra

Abgesehen von der Lesbarkeit, gibt es erkennbare Unterschiede (möglicherweise bei der Leistung) zwischen der Verwendung von

str.indexOf("src") 

und

str.match(/src/)

Ich persönlich bevorzuge match (und regexp), aber die Kollegen scheinen den anderen Weg zu gehen. Wir haben uns gefragt, ob es wichtig ist …?

BEARBEITEN:

Ich hätte eingangs sagen sollen, dass dies für Funktionen gilt, die einen teilweisen Abgleich von einfachen Zeichenfolgen durchführen (um Bezeichner in Klassenattributen für JQuery abzurufen), anstatt vollständige Regexp-Suchen mit Platzhaltern usw.

class="redBorder DisablesGuiClass-2345-2d73-83hf-8293" 

Es ist also der Unterschied zwischen:

string.indexOf('DisablesGuiClass-');

und

string.match(/DisablesGuiClass-/)

  • Ich finde str.indexOf("xyz") verglichen werden soll /xyz/.test(str)

    – Redu

    9. Juni 2016 um 5:12 Uhr

  • hier ein Benchmark, der indexOf, regex und match vergleicht jsben.ch/#/r9hBp

    – EscapeNetscape

    21. Oktober 2016 um 22:02 Uhr

  • Eigentlich String.prototype.indexOf eher vergleichbar ist String.prototype.search da beide den Startindex des Spiels zurückgeben. Der boolesche Ausdruck 'foo'.indexOf('bar') !== -1 ist besser vergleichbar mit /bar/.test('foo') weil beide einen booleschen Wert ergeben. Für einfache Ausdrücke ohne Gruppen und Anker sollte die Leistung jedoch vergleichbar sein. str.match verschwendet zu viel, weil es alle Übereinstimmungen zurückgibt, und ich würde davon abraten, es für Vergleiche zu verwenden. Das heißt, wenn Sie kein Leistungsproblem haben, wählen Sie das besser lesbare.

    – Thorsten Walter

    10. Januar 2019 um 10:00 Uhr


RegExp ist tatsächlich langsamer als indexOf (man sieht es hier), obwohl dies normalerweise kein Problem sein sollte. Bei RegExp müssen Sie auch sicherstellen, dass die Zeichenfolge richtig maskiert ist, was eine zusätzliche Sache ist, über die Sie nachdenken müssen.

Abgesehen von diesen beiden Problemen, wenn zwei Tools genau das tun, was Sie brauchen, warum wählen Sie dann nicht das einfachere?

  • Macht für mich Sinn, von nun an werden wir mit laufen indexOf sofern keine zusätzliche RegExp-Funktionalität erforderlich ist. Danke vielmals! PS. Die konfigurierbare Testseite, auf die Sie in Ihrer Antwort verlinkt haben, ist cool – ist sie öffentlich zugänglich oder etwas, das Sie sich selbst ausgedacht haben?

    – Indra

    21. Januar 2011 um 11:12 Uhr


  • @5arx, jsperf ist wie jsfiddle ein unverzichtbares Tool zum schnellen Testen von Ideen. Es ist eine öffentliche Seite, gehen Sie einfach zu jsperf.com und erstellen Sie Ihre eigenen Tests.

    – David Tang

    21. Januar 2011 um 11:15 Uhr

  • Laut diesem jsperf-Test stimmt es einfach nicht, dass indexOf immer schnell ist: stackoverflow.com/a/5296314/981933

    – F. Lekschas

    8. Oktober 2013 um 7:17 Uhr

  • Der Test, auf den Sie sich beziehen, kann genau sein oder auch nicht – er hat mit Sicherheit den RegExp falsch gemacht, was kein Vertrauen weckt. '[\\?|&]' sollte sein [?&] entweder passen ? oder & – keine Notwendigkeit für ein | Betreiber, noch das Entkommen der ?.

    – Lee Goddard

    2. März 2016 um 8:38 Uhr

  • Nur um historische Farbe hinzuzufügen: Zum Datum dieses Kommentars sagt der in der Antwort verlinkte Test auf meinem Computer (2017 MBP mit Chrome 56.0.2924 unter Mac OS X 10.12.3), dass die indexOf ist 12 % langsamer als der Regex-Match. Bei vielen Dingen lautet die richtige Antwort also wohl: Es kommt darauf an.

    – davemyron

    20. März 2017 um 21:17 Uhr

Benutzer-Avatar
Tim Pietzcker

Ihr Vergleich ist möglicherweise nicht ganz fair. indexOf wird mit glatten Saiten verwendet und ist daher sehr schnell; match nimmt einen regulären Ausdruck – natürlich kann es im Vergleich langsamer sein, aber wenn Sie einen Regex-Match machen wollen, werden Sie damit nicht weit kommen indexOf. Andererseits können Engines für reguläre Ausdrücke optimiert werden und haben sich in den letzten Jahren in ihrer Leistung verbessert.

In Ihrem Fall, wo Sie nach einer wörtlichen Zeichenfolge suchen, indexOf sollte ausreichen. Es gibt jedoch immer noch eine Anwendung für reguläre Ausdrücke: Wenn Sie übereinstimmen müssen gesamte Wörter und möchten übereinstimmende Teilzeichenfolgen vermeiden, dann geben Ihnen reguläre Ausdrücke “Wortgrenzenanker”. Zum Beispiel:

indexOf('bar')

wird finden bar dreimal drin bar, fubar, barmywohingegen

match(/\bbar\b/)

wird nur passen bar wenn es nicht Teil eines längeren Wortes ist.

Wie Sie in den Kommentaren sehen können, wurden einige Vergleiche durchgeführt, die zeigen, dass eine Regex möglicherweise schneller ist als indexOf – Wenn es leistungskritisch ist, müssen Sie Ihren Code möglicherweise profilieren.

  • Ich hielt es für eine faire Frage, die aus einem Perl-Hintergrund stammt, wo eine äquivalente Regex schneller ist als indexOf.

    – Lee Goddard

    2. März 2016 um 8:39 Uhr

  • Es ist kein Vergleich zwischen Äpfeln und Birnen, da eine triviale Regex so schnell wie möglich optimiert werden kann indexOf. Ich bin gerade gelaufen jsperf.com/substring-test und es behauptet, dass “regex case insensitive” am schnellsten und 30% schneller ist als “indexOf”, was ich nicht glauben möchte.

    – maaartinus

    29. Mai 2017 um 1:45 Uhr

  • Während indexOf jede dieser Zeichenfolgen finden würde, findet es nur den ersten „Balken“ in der Zeichenfolge.

    – PRMan

    21. Juni um 15:12 Uhr

Hier alle Möglichkeiten (relativ), nach Strings zu suchen

// 1. beinhaltet (eingeführt in ES6)

var string = "string to search for substring",
    substring = "sea";
string.includes(substring);

// 2. string.indexOf

var string = "string to search for substring",
    substring = "sea";
string.indexOf(substring) !== -1;

// 3. RegExp: test

var string = "string to search for substring",
    expr = /sea/;  // no quotes here
expr.test(string);

// 4. string.übereinstimmung

var string = "string to search for substring",
    expr = "/sea/";
string.match(expr);

//5. Zeichenfolge.Suche

var string = "string to search for substring",
    expr = "/sea/";
string.search(expr);

Hier ein src: https://koukia.ca/top-6-ways-to-search-for-a-string-in-javascript-and-performance-benchmarks-ce3e9b81ad31

Benchmarks scheinen speziell für es6-Includes verdreht zu sein, lesen Sie die Kommentare.

Zusammenfassend:

wenn Sie die Streichhölzer nicht brauchen. => Entweder Sie brauchen Regex und verwenden es so Prüfung. Sonst es6 beinhaltet oder Index von. Still Prüfung vs Index von sind nahe.

Und für include vs indexOf:

Sie scheinen gleich zu sein: https://jsperf.com/array-indexof-vs-includes/4 (Wenn es anders wäre, wäre es seltsam, sie verhalten sich meistens gleich, abgesehen von den Unterschieden, die sie aufdecken Überprüfen Sie dies)

Und für meinen eigenen Benchmark-Test. Hier ist es http://jsben.ch/fFnA0
Sie können es testen (es ist browserabhängig) [test multiple time]
Hier, wie es funktioniert hat (mehrere Läufe indexOf und enthält einen Schlag gegen den anderen, und sie sind nah dran). Sie sind also gleich. [here using the same test platform as the article above].

Geben Sie hier die Bildbeschreibung ein
Geben Sie hier die Bildbeschreibung ein

Und hier für die lange Textversion (8 mal länger)
http://jsben.ch/wSBA2

Geben Sie hier die Bildbeschreibung ein

Chrome und Firefox getestet, dasselbe.

Beachten Sie, dass jsben.ch den Speicherüberlauf nicht handhabt (oder es gibt keine korrekten Grenzen. Es wird keine Meldung angezeigt), sodass das Ergebnis falsch werden kann, wenn Sie mehr als 8 Textduplizierungen hinzufügen (8 funktionieren gut). Aber die Schlussfolgerung ist, dass bei sehr großem Text alle drei auf die gleiche Weise funktionieren. Ansonsten sind kurz indexOf und Includes gleich und testen etwas langsamer. oder Kann das gleiche sein, wie es in Chrome schien (Firefox 60 ist langsamer).

Hinweis bei jsben.ch: Nicht ausflippen, wenn Sie ein inkonsistentes Ergebnis erhalten. Probieren Sie eine andere Zeit aus und sehen Sie, ob sie konsistent ist oder nicht. Browser wechseln, manchmal laufen sie einfach total falsch. Fehler oder schlechte Handhabung des Speichers. Oder so.

ex:

Geben Sie hier die Bildbeschreibung ein

Auch hier mein Benchmark zu jsperf (bessere Details und handhabbare Grafiken für mehrere Browser)

(oben ist Chrom)

normaler Text
https://jsperf.com/indexof-vs-includes-vs-test-2019
fortsetzen: include und indexOf haben die gleiche Leistung. langsamer testen.

Geben Sie hier die Bildbeschreibung ein
Geben Sie hier die Bildbeschreibung ein

(scheinen alle drei in chrom gleich zu machen)

Langer Text (12 mal länger als normal)
https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
fortsetzen: Alle drei verhalten sich gleich. (Chrom und Firefox)
Geben Sie hier die Bildbeschreibung ein

sehr kurze Saite
https://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
fortsetzen: Includes und IndexOf führen dasselbe aus und testen langsamer.

Geben Sie hier die Bildbeschreibung ein

Hinweis: über den Benchmark oben. Für die sehr kurze Saite Version (jsperf) hatte einen großen Fehler für Chrome. Mit meinen Augen sehen. Etwa 60 Samples wurden sowohl für indexOf als auch für include auf die gleiche Weise ausgeführt (viele Male wiederholt). Und teste ein bisschen weniger und damit langsamer. Lassen Sie sich nicht mit dem falschen Diagramm täuschen. Es ist eindeutig falsch. Gleiche Testarbeit ok für Firefox, sicher ist es ein Fehler.

Hier die Illustration: (das erste Bild war der Test auf Firefox)
Geben Sie hier die Bildbeschreibung ein

waaaa. Plötzlich wurde indexOf zu Superman. Aber wie gesagt, ich habe den Test gemacht und mir die Anzahl der Samples angesehen, die ungefähr 60 waren. Sowohl indexOf als auch include und sie haben die gleiche Leistung erbracht. Ein Fehler an jspref. Abgesehen von diesem (vielleicht wegen eines Problems mit Speicherbeschränkungen) war der Rest konsistent, es gibt mehr Details. Und Sie sehen, wie viele einfache Dinge in Echtzeit passieren.

Endgültiger Lebenslauf

indexOf vs enthält => Gleiche Leistung

Prüfung => kann für kurze Zeichenfolgen oder Text langsamer sein. Und das gleiche bei langen Texten. Und es macht Sinn für den Overhead, den die Regex-Engine hinzufügt. In Chrom schien es überhaupt keine Rolle zu spielen.

  • :daumen hoch: für die mühe 🙂

    – Ajay Kumar Ganesh

    12. April 2019 um 14:27 Uhr

Wenn Sie versuchen, nach Vorkommen von Teilzeichenfolgen zu suchen case-insensitive dann match scheint schneller zu sein als eine Kombination aus indexOf und toLowerCase()

Überprüfe hier – http://jsperf.com/regexp-vs-indexof/152

Du fragst ob str.indexOf('target') oder str.match(/target/) sollte bevorzugt werden. Wie andere Poster angedeutet haben, sind die Anwendungsfälle und Rückgabetypen dieser Methoden unterschiedlich. Der erste fragt: „wo in str kann ich zuerst finden 'target'?” Der zweite fragt. “Tut str stimmen mit der Regex überein, und wenn ja, wie lauten alle Übereinstimmungen für alle zugehörigen Capture-Gruppen?”

Das Problem ist, dass keines der beiden technisch dafür ausgelegt ist, die einfachere Frage zu stellen: “Enthält die Zeichenfolge die Teilzeichenfolge?” Es gibt etwas, das explizit dafür vorgesehen ist:

var doesStringContainTarget = /target/.test(str);

Die Verwendung hat mehrere Vorteile regex.test(string):

  1. Es gibt einen booleschen Wert zurück, was Sie interessiert
  2. Es ist leistungsfähiger als str.match(/target/) (und Konkurrenten str.indexOf('target'))
  3. Wenn aus irgendeinem Grund str ist undefined oder nullDu wirst kriegen false (das gewünschte Ergebnis) anstatt a zu werfen TypeError

Benutzer-Avatar
Lukas H

Verwenden indexOf sollte theoretisch schneller sein als eine Regex, wenn Sie nur nach einfachem Text suchen, aber Sie sollten selbst einige vergleichende Benchmarks durchführen, wenn Sie sich Sorgen um die Leistung machen.

Wenn Sie es vorziehen match und es ist schnell genug für Ihre Bedürfnisse, dann machen Sie es.

Für das, was es wert ist, stimme ich Ihren Kollegen darin zu: Ich würde verwenden indexOf bei der Suche nach einer einfachen Zeichenfolge und verwenden match etc nur, wenn ich die zusätzliche Funktionalität benötige, die durch reguläre Ausdrücke bereitgestellt wird.

Benutzer-Avatar
ChaosPandion

Leistungsmäßig indexOf wird zumindest etwas schneller sein als match. Auf die konkrete Umsetzung kommt es an. Stellen Sie sich bei der Entscheidung, welche Sie verwenden möchten, die folgende Frage:

Reicht ein ganzzahliger Index oder benötige ich die Funktionalität eines RegExp-Match-Ergebnisses?

1082210cookie-checkJavaScript: indexOf vs. Match beim Suchen von Strings?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy