2011-06-05 10 views
5

Al leer este SO post-Is there a version of JavaScript's String.indexOf() that allows for regular expressions?) que reflexionar sobre cuál de las dos funciones que buscan el último grupo más grande de espacio en blanco() en txt funcione más rápido (o tienen diferencias en tiempo de ejecución insignificante)expresiones regulares vs mientras que los bucles

 
(function(str) 
{ 
    var result = /\s+(?!.*\s+)/.exec(str); 
    return ((result)? result.index : -1); 
})(txt); 

o

 
(function(str) 
{ 
    var regex = /\s+/g; 
    var result; 
    var index = -1; 
    while(result = regex.exec(str)) 
    { 
     index = result.index; 
    } 
    return index; 
})(txt); 

brevemente, el primero utiliza una expresión expresión regular para buscar un grupo de espacio en blanco que no está seguida por ningún otro grupo de espacio en blanco, y la segunda utiliza un bucle while.

Cualquier ayuda con esta cuestión es muy apreciada.

+1

Siempre puede [pruebe los dos enfoques y vea!] (Http://jsperf.com) – Pointy

+1

Su segunda función es incorrecta. Necesita ser 'index = result.index' en lugar de' index + = result.index'. – Gumbo

+0

Mi enfoque es siempre hacer la más simple o al menos la más sensata del grupo y dejar que los expertos optimicen el compilador. En general, podría averiguar qué método es el más rápido y seguir con él, pero debería verificar todos los navegadores y, en general, los cambios en el tiempo de ejecución de los lenguajes y está optimizado todo el tiempo, entonces, ¿cuál es el más rápido ahora? manejar la optimización a menos que específicamente tenga problemas. – Jonathon

Respuesta

2
(function(str) 
{ 
    var result = /\s+(?!.*\s+)/.exec(str); 
    return ((result)? result.index : -1); 
})(txt); 

está roto. Coincidirá con " \n" porque . no coincide con todos los caracteres de espacio. Específicamente, no coincide con los caracteres de espacio "\r\n\u2028\u2029" que coinciden con \s.

Si quieres una buena manera para que coincida con el último (el más grande) Grupo de espacio en blanco en txt, utilice el RegExp a continuación con String.prototype.search:

var indexOfStartOfLastWhitespaceGroup = str.search(/\s+\S*$/); 

Para obtener el índice final, no se puede utilizar la propiedad .lastIndex de la expresión regular ya que incluye la parte \S*. Puede usar .search nuevamente.

if (indexOfStartOfLastWhitespaceGroup >= 0) { 
    var indexOfEndOfLastWhitespaceGroup = str.search(/\S*$/); 
    ... 
} 

que reflexionar sobre cuál de las dos funciones que buscan la última (más grande) Grupo de espacio en blanco en el plazo txt más rápido (o tienen diferencias en tiempo de ejecución insignificante)

Para los pequeños cadenas, el resultado es probablemente insignificante sin importar el método (correcto) que use. Para cadenas grandes, iterar sobre toda la cadena va a ser costoso, por lo que la mejor opción es usar una expresión regular anclada al final, es decir, tiene $ como el último token y no tiene ^ en ella. Un intérprete puede perder tiempo haciendo una búsqueda de cadenas completa cuando hay una expresión regular anclada solo a la derecha, pero creo que la mayoría hace esta simple optimización.

Esto es lo que obtengo en squarefree shell bajo cromo.

var s = ''; 
for (var i = 10000; --i >= 0;) s += 'abba'; 
s += 'foo'; 
var t0 = Date.now(); for (var i = 100; --i >= 0;) /foo$/.test(s); var t1 = Date.now(); 
var t2 = Date.now(); for (var i = 100; --i >= 0;) /abbafoo/.test(s); var t3 = Date.now(); 
[t1 - t0, t3 - t2] 
// emits [1, 8] 

Por último, se debe tener en cuenta que \s no siempre significa lo mismo en todos los intérpretes. /\s/.test("\xA0") que prueba si el espacio sin interrupción (piense  ) es un espacio es falso en IE 6 pero es cierto en la mayoría de los intérpretes de otros navegadores (no estoy seguro acerca de IE 7+).

+0

Muchas gracias; eso es muy informativo – knight

1

Puede usar jsPerf para comparar el rendimiento de diferentes fragmentos de JavaScript. He creado one that uses your two variants and this one by me:

function(str) { 
    var parts = str.split(/(?=\s+)/); 
    return parts.length === 1 ? -1 : str.length - parts[parts.length-1].length; 
} 

Es básicamente divide la cadena en la posición del partido usando una afirmación de preanálisis. Si no se encuentra ninguna coincidencia, split devuelve una matriz con solo un elemento; de lo contrario, la longitud de la última parte se resta de la longitud total de la cadena para obtener el índice de la última coincidencia.


actualización he ajustado las funciones de un poco y ahora tenemos algunos completamente diferente en comparación con el resultsprevious benchmark. Ahora la primera función que ahora está usando /\s+(?!\S+\s+)/ en lugar de /\s+(?!.*\s+)/ parece ser la más rápida.

+0

Estoy pensando en tu código, y no tengo idea de por qué era mucho más rápido que los dos que tenía en mente. ¿Porqué es eso? – knight

Cuestiones relacionadas