¿La solución más rápida?
Ejecuté algunos puntos de referencia , y esta solución ganó enormemente: 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);
};
Comparación de rendimiento con otras soluciones.
El único competidor cercano era la misma línea de código, excepto el uso en substr
lugar de slice
.
Otras soluciones que probé involucrando split
o RegExp
s tuvieron un gran éxito de rendimiento y fueron aproximadamente 2 órdenes de magnitud más lentas. Usar join
los resultados de split
, por supuesto, agrega una penalización de rendimiento adicional.
¿Por qué son más lentos? Cada vez que se debe crear un nuevo objeto o matriz, JS tiene que solicitar una porción de memoria del sistema operativo. Este proceso es muy lento.
Aquí hay algunas pautas generales, en caso de que esté persiguiendo puntos de referencia:
- Las nuevas asignaciones de memoria dinámica para objetos
{}
o matrices []
(como la que split
crea) costarán mucho en rendimiento.
RegExp
Las búsquedas son más complicadas y, por lo tanto, más lentas que las búsquedas de cadenas.
- Si ya tiene una matriz, la desestructuración de las matrices es casi tan rápida como indexarlas explícitamente, y se ve increíble.
Eliminar más allá de la primera instancia
Aquí hay una solución que se dividirá e incluirá la enésima instancia. No es tan rápido, pero en la pregunta del OP, gobble(element, '_', 1)
todavía es> 2 veces más rápido que una RegExp
o split
solución y puede hacer más:
/*
`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);
}
Con la definición anterior, gobble('path/to/file.txt', '/')
daría el nombre del archivo y gobble('prefix_category_item', '_', 1)
eliminaría el prefijo como la primera solución en esta respuesta.
- Las pruebas se ejecutaron en Chrome 70.0.3538.110 en macOSX 10.14.