La solution la plus rapide?
J'ai couru quelques benchmarks , et cette solution a énormément gagné: 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);
};
Comparaison des performances avec d'autres solutions
Le seul concurrent proche était la même ligne de code, sauf en utilisant substr
au lieu de slice
.
D'autres solutions que j'ai essayé d'impliquer split
ou ont RegExp
pris un gros coup de performance et étaient environ 2 ordres de grandeur plus lents. L'utilisation join
des résultats split
ajoute, bien sûr, une pénalité de performance supplémentaire.
Pourquoi sont-ils plus lents? Chaque fois qu'un nouvel objet ou tableau doit être créé, JS doit demander un morceau de mémoire au système d'exploitation. Ce processus est très lent.
Voici quelques directives générales, au cas où vous poursuivriez des repères:
- Nouvelles allocations de mémoire dynamique pour les objets
{}
ou les tableaux []
(comme celui qui split
crée) coûteront beaucoup en performances.
RegExp
les recherches sont plus compliquées et donc plus lentes que les recherches de chaînes.
- Si vous avez déjà un tableau, la déstructuration des tableaux est à peu près aussi rapide que leur indexation explicite, et a l'air génial.
Suppression au-delà de la première instance
Voici une solution qui découpera jusqu'à et incluant la nième instance. Ce n'est pas aussi rapide, mais sur la question de l'OP, il gobble(element, '_', 1)
est toujours> 2x plus rapide qu'une solution RegExp
or split
et peut faire plus:
/*
`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);
}
Avec la définition ci-dessus, gobble('path/to/file.txt', '/')
donnerait le nom du fichier et gobble('prefix_category_item', '_', 1)
supprimerait le préfixe comme la première solution dans cette réponse.
- Les tests ont été exécutés dans Chrome 70.0.3538.110 sur macOSX 10.14.