Schnellste Lösung?
Ich habe einige Benchmarks durchgeführt , und diese Lösung hat enorm gewonnen: 1
str.slice(str.indexOf(delim) + delim.length)
// as function
function gobbleStart(str, delim) {
return str.slice(str.indexOf(delim) + delim.length);
}
// as polyfill
String.prototype.gobbleStart = function(delim) {
return this.slice(this.indexOf(delim) + delim.length);
};
Leistungsvergleich mit anderen Lösungen
Der einzige enge Anwärter war dieselbe Codezeile, außer dass substr
anstelle von slice
.
Andere Lösungen, die ich mit split
oder ohne RegExp
s versucht habe, hatten einen großen Leistungseinbruch und waren etwa 2 Größenordnungen langsamer. Die Verwendung join
der Ergebnisse von split
fügt natürlich eine zusätzliche Leistungsstrafe hinzu.
Warum sind sie langsamer? Jedes Mal, wenn ein neues Objekt oder Array erstellt werden muss, muss JS einen Speicherblock vom Betriebssystem anfordern. Dieser Prozess ist sehr langsam.
Hier sind einige allgemeine Richtlinien für den Fall, dass Sie Benchmarks verfolgen:
- Neue dynamische Speicherzuordnungen für Objekte
{}
oder Arrays []
(wie die, die split
erstellt werden) kosten viel Leistung.
RegExp
Suchen sind komplizierter und daher langsamer als Zeichenfolgensuchen.
- Wenn Sie bereits über ein Array verfügen, ist die Destrukturierung von Arrays ungefähr so schnell wie die explizite Indizierung und sieht fantastisch aus.
Über die erste Instanz hinaus entfernen
Hier ist eine Lösung, die bis zur n-ten Instanz reicht. Es ist nicht ganz so schnell, aber auf die Frage des OP gobble(element, '_', 1)
ist es immer noch> 2x schneller als eine RegExp
oder split
Lösung und kann mehr:
/*
`gobble`, given a positive, non-zero `limit`, deletes
characters from the beginning of `haystack` until `needle` has
been encountered and deleted `limit` times or no more instances
of `needle` exist; then it returns what remains. If `limit` is
zero or negative, delete from the beginning only until `-(limit)`
occurrences or less of `needle` remain.
*/
function gobble(haystack, needle, limit = 0) {
let remain = limit;
if (limit <= 0) { // set remain to count of delim - num to leave
let i = 0;
while (i < haystack.length) {
const found = haystack.indexOf(needle, i);
if (found === -1) {
break;
}
remain++;
i = found + needle.length;
}
}
let i = 0;
while (remain > 0) {
const found = haystack.indexOf(needle, i);
if (found === -1) {
break;
}
remain--;
i = found + needle.length;
}
return haystack.slice(i);
}
Mit der obigen Definition gobble('path/to/file.txt', '/')
würde der Name der Datei angegeben und gobble('prefix_category_item', '_', 1)
das Präfix wie bei der ersten Lösung in dieser Antwort entfernt.
- Die Tests wurden in Chrome 70.0.3538.110 unter macOSX 10.14 ausgeführt.