Najszybsze rozwiązanie?
Przeprowadziłem kilka testów porównawczych , a to rozwiązanie odniosło ogromny sukces: 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);
};
Porównanie wydajności z innymi rozwiązaniami
Jedynym konkurentem był ten sam wiersz kodu, z wyjątkiem użycia substr
zamiast slice
.
Inne rozwiązania próbowałem udziałem split
lub RegExp
s wziął duży spadek wydajności i były o 2 rzędy wielkości wolniejsze. Korzystanie join
z wyników split
oczywiście dodaje dodatkową utratę wydajności.
Dlaczego są wolniejsze? Za każdym razem, gdy trzeba utworzyć nowy obiekt lub tablicę, JS musi zażądać części pamięci od systemu operacyjnego. Ten proces jest bardzo wolny.
Oto kilka ogólnych wskazówek na wypadek, gdy ścigasz testy porównawcze:
- Nowe dynamiczne alokacje pamięci dla obiektów
{}
lub tablic []
(takich jak te, które split
tworzą) będą dużo kosztować wydajność.
RegExp
wyszukiwanie jest bardziej skomplikowane, a zatem wolniejsze niż wyszukiwanie ciągów.
- Jeśli masz już tablicę, tablice destrukcyjne są tak samo szybkie, jak ich bezpośrednie indeksowanie i wyglądają świetnie.
Usuwanie poza pierwszą instancją
Oto rozwiązanie, które podzieli na n-tą instancję włącznie. To nie jest tak szybkie, ale na pytanie PO, gobble(element, '_', 1)
jest wciąż> 2x szybsze niż rozwiązanie RegExp
lub split
i może zrobić więcej:
/*
`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);
}
Przy powyższej definicji gobble('path/to/file.txt', '/')
podałby nazwę pliku i gobble('prefix_category_item', '_', 1)
usunąłby przedrostek jak pierwsze rozwiązanie w tej odpowiedzi.
- Testy przeprowadzono w Chrome 70.0.3538.110 na macOSX 10.14.