it-swarm.com.de

JavaScript: indexOf vs. Übereinstimmung beim Durchsuchen von Strings?

Abgesehen von der Lesbarkeit gibt es erkennbare Unterschiede (Leistung) zwischen der Verwendung 

str.indexOf("src") 

und 

str.match(/src/)

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

BEARBEITEN:

Ich hätte zu Beginn sagen sollen, dass dies für Funktionen gedacht ist, die einen partiellen Klartextabgleich durchführen (um Bezeichner in Klassenattributen für JQuery aufzunehmen), und nicht vollständige regexp-Suchen mit Platzhaltern usw.

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

Es ist also der Unterschied zwischen:

string.indexOf('DisablesGuiClass-');

VS

string.match(/DisablesGuiClass-/)
57
indra

RegExp ist in der Tat langsamer als indexOf (Sie können es hier sehen), obwohl dies normalerweise kein Problem sein sollte. Mit RegExp müssen Sie außerdem sicherstellen, dass die Zeichenfolge ordnungsgemäß maskiert ist. Dies ist eine zusätzliche Sache, über die Sie nachdenken müssen.

Abgesehen von diesen beiden Aspekten: Wenn zwei Tools genau das tun, was Sie benötigen, wählen Sie das einfachere.

51
David Tang

Ihr Vergleich ist möglicherweise nicht ganz fair. indexOf wird mit einfachen Strings verwendet und ist daher sehr schnell. match nimmt einen regulären Ausdruck - im Vergleich dazu kann es natürlich langsamer sein, aber wenn Sie einen Regex-Abgleich durchführen möchten, werden Sie mit indexOf nicht weit kommen. Auf der anderen Seite können reguläre Ausdrücke optimiert werden und ihre Leistung in den letzten Jahren verbessert haben.

In Ihrem Fall, wenn Sie nach einer wörtlichen Zeichenfolge suchen, sollte indexOf ausreichend sein. Es gibt jedoch immer noch eine Anwendung für Regex: Wenn Sie Wörter mit ganze suchen und keine übereinstimmenden Teilzeichenfolgen verwenden möchten, erhalten Sie mit regulären Ausdrücken "Wortbegrenzungsanker". Zum Beispiel:

indexOf('bar')

findet bar dreimal in bar, fubar, barmy, wohingegen

match(/\bbar\b/)

wird nur mit bar übereinstimmen, wenn es nicht Teil eines längeren Wortes ist.

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

19
Tim Pietzcker

Wenn Sie nach Teilzeichenfolgen suchen case-insensitively suchen, scheint match schneller zu sein als eine Kombination aus indexOf und toLowerCase().

Überprüfen Sie hier - http://jsperf.com/regexp-vs-indexof/152

8
Yogesh Mangaj

Sie fragen, ob str.indexOf('target') oder str.match(/target/) bevorzugt werden soll. Wie von anderen Postern vorgeschlagen, unterscheiden sich die Anwendungsfälle und Rückgabetypen dieser Methoden. Der erste fragt "Wo finde ich in str zuerst 'target'?" Der zweite fragt "Stimmt str mit dem regulären Ausdruck überein und wenn ja, wie lauten alle Übereinstimmungen für zugeordnete Erfassungsgruppen?"

Das Problem ist, dass keiner von beiden technisch die einfachere Frage stellt: "Enthält der String den Teilstring?" Es gibt etwas, das ausdrücklich dafür entworfen wurde:

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

Die Verwendung von regex.test(string) bietet mehrere Vorteile:

  1. Es gibt einen Booleschen Wert zurück, den Sie interessieren
  2. Es ist performanter als str.match(/target/) (und Rivalen str.indexOf('target'))
  3. Wenn str aus irgendeinem Grund undefined oder null ist, wird false (das gewünschte Ergebnis) angezeigt, anstatt eine TypeError zu werfen.
6
elreimundo

Die Verwendung von indexOf sollte theoretisch schneller sein als ein Regex, wenn Sie nur nach Text suchen, aber Sie sollten selbst einige vergleichende Benchmarks durchführen, wenn Sie sich um die Leistung sorgen.

Wenn Sie match bevorzugen und es für Ihre Bedürfnisse schnell genug ist, dann entscheiden Sie sich dafür.

Ich stimme mit Ihren Kollegen dazu überein: Ich würde indexOf verwenden, wenn Sie nach einer einfachen Zeichenfolge suchen, und match usw. nur, wenn ich die zusätzliche Funktionalität benötige, die reguläre Ausdrücke bieten.

5
LukeH

Performance wise indexOf ist zumindest etwas schneller als match. Auf die konkrete Implementierung kommt es an. Bei der Entscheidung, welche Anwendung Sie verwenden möchten, stellen Sie sich folgende Frage: 

Wird ein ganzzahliger Index ausreichen oder muss ich benötigen die Funktionalität eines RegExp Übereinstimmungsergebnis

4
ChaosPandion

Die Rückgabewerte sind unterschiedlich

Abgesehen von den Auswirkungen auf die Leistung, auf die andere Antworten eingehen, ist zu beachten, dass die Rückgabewerte für jede Methode unterschiedlich sind. Die Methoden können also nicht einfach ersetzt werden, ohne auch Ihre Logik zu ändern.

Rückgabewert von .indexOf : integer

Der Index innerhalb des aufrufenden String-Objekts des ersten Vorkommens des angegebenen Werts. Die Suche beginnt mit fromIndex.
Gibt -1 zurück, wenn der Wert nicht gefunden wird.

Rückgabewert von .match : array

Ein Array, das das gesamte Übereinstimmungsergebnis und alle übereinstimmenden Ergebnisse in Klammern enthält.
Gibt null zurück, wenn keine Übereinstimmungen vorhanden waren.

Da .indexOf0 zurückgibt, wenn die aufrufende Zeichenfolge beginnt mit dem angegebenen Wert ausgegeben wird, schlägt ein einfacher Test fehl.

Zum Beispiel:

In dieser Klasse…

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

… Die Rückgabewerte für jeden würden sich unterscheiden:

//  returns `0`, evaluates to `false`
if (string.indexOf('DisablesGuiClass-')) {
    … // this block is skipped.
}

vs.

//  returns `["DisablesGuiClass-"]`, evaluates to `true`
if (string.match(/DisablesGuiClass-/)) { 
    … // this block is run.
}

Der korrekte Weg, um einen wahrheitsgemäßen Test mit der Rückgabe von .indexOf auszuführen, ist der Test gegen -1:

if (string.indexOf('DisablesGuiClass-') !== -1) {
//  ^returns `0`                        ^evaluates to `true`
    … // this block is run.
}
3
gfullam

denken Sie daran, dass Internet Explorer 8 indexOf..__ nicht versteht. Wenn jedoch keiner Ihrer Benutzer ie8 verwendet (Google Analytics würde Sie darauf hinweisen), lassen Sie diese Antwort aus. Mögliche Lösung, um ie8 zu beheben: So beheben Sie Array indexOf () in JavaScript für Internet Explorer-Browser

0
NoWomenNoCry

verwenden Sie immer indexOf für das Vorhandensein von Teilzeichenfolgen und match nur dann, wenn Sie sie wirklich benötigen. Wenn Sie also nach Wordsrc in einer Zeichenfolge suchen, die auch altsrc enthalten könnte, ist aString.match(/\bsrc\b/) in der Tat geeigneter.

0
Walf

Hier alle möglichen Wege (relativ) nach String zu suchen 

// 1. umfasst (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.match

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

// 5. string.search

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 verdreht zu sein, lesen Sie die Kommentare.

Zusammenfassend:

wenn Sie die Spiele nicht brauchen. => Entweder Sie benötigen einen regulären Ausdruck und verwenden daher test. Ansonsten es6 schließt oder indexOf ein. Noch sind test vs indexOf nahe.

Und für include vs indexOf:

Sie scheinen die gleichen zu sein: https://jsperf.com/array-indexof-vs-includes/4 (Wenn es anders wäre, wäre es komisch, führen sie meistens dasselbe aus, abgesehen von den Unterschieden, die sie offenlegen Ü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 vom Browser abhängig) [test multiple time und sie sind nahe). Sie sind also gleich. [hier mit derselben Testplattform wie im obigen Artikel].

 enter image description here  enter image description here

Und hier zur Langtextversion (8-mal länger) http://jsben.ch/wSBA2

 enter image description here

Getestet sowohl Chrom als auch Firefox, dasselbe.

Beachten Sie, dass jsben.ch den Speicherüberlauf nicht behandelt (oder die Begrenzungen nicht korrekt sind. Es wird keine Meldung angezeigt). Das Ergebnis kann fehlerhaft sein, wenn Sie mehr als 8 Textvervielfältigungen hinzufügen (8 funktionieren gut). Die Schlussfolgerung ist jedoch, dass bei sehr großen Texten alle drei auf dieselbe Weise funktionieren. Ansonsten für kurze IndexOf und Includes sind die gleichen und testen etwas langsamer. oder Kann das gleiche sein, wie es in Chrom vorkam (Firefox 60 ist langsamer).

Beachten Sie bei jsben.ch: Fallen Sie nicht aus, wenn Sie inkonsistente Ergebnisse erhalten. Versuchen Sie es einmal anders und sehen Sie, ob es konsistent ist oder nicht. Browser wechseln, manchmal laufen sie völlig falsch. Fehler oder falscher Umgang mit dem Speicher. Oder so.

ex:

 enter image description here

Auch hier mein Benchmark auf jsperf (bessere Details und Graphen für mehrere Browser)

(oben ist Chrom)

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

 enter image description here  enter image description here (scheinen alle drei in chrom gleich zu sein)

Langtext (12 Mal länger als normal) https://jsperf.com/indexof-vs-includes-vs-test-2019-long-text-str/
resume: Alle drei führen dasselbe aus. (Chrom und Firefox)  enter image description here

sehr kurze Zeichenfolgehttps://jsperf.com/indexof-vs-includes-vs-test-2019-too-short-string/
resume: include und indexOf führen dasselbe aus und testen langsamer.

 enter image description here

Anmerkung: über den Benchmark oben. Bei der very short string -Version (jsperf) gab es einen großen Fehler für Chrome. Mit meinen Augen sehen. Es wurden ungefähr 60 Proben für beide IndexOf-Programme erstellt und enthalten denselben Weg (wiederholt wiederholt). Und testen Sie ein bisschen weniger und so langsamer ... __, lassen Sie sich nicht mit der falschen Grafik täuschen. Es ist eindeutig falsch. Dieselbe Testarbeit für Firefox ist in Ordnung, sicherlich ist es ein Fehler. 

Hier die Abbildung: (das erste Bild war der Test mit Firefox)  enter image description here waaaa. Plötzlich wurde indexOf zum Übermenschen. Aber wie gesagt, ich habe den Test gemacht und die Anzahl der Proben auf etwa 60 geschätzt. Beide IndexOf und Includes und sie haben das gleiche gemacht. Ein Fehler in jspref. Abgesehen von diesem Problem (möglicherweise aufgrund eines Problems mit der Einschränkung des Speichers) war der Rest gleichbleibend, er enthält weitere Details. Und Sie sehen, wie viele einfache Ereignisse in Echtzeit passieren.

Finaler Lebenslauf

indexOf vs umfasst => Gleiche Leistung

test => kann für kurze Zeichenfolgen oder Text langsamer sein. Dasselbe gilt für lange Texte. Und es macht Sinn für den Overhead, den die Regex-Engine hinzufügt. In Chrom schien es überhaupt keine Rolle zu spielen. 

0
Mohamed Allal