util sheet matches cheat java regex

sheet - java util regex



regex VS Contiene. ¿Mejor presentación? (7)

Quiero comparar una cadena URI sobre diferentes patrones en java y quiero el código más rápido posible.

Debería usar:

if(uri.contains("/br/fab") || uri.contains("/br/err") || uri.contains("/br/sts")

O algo como:

if(uri.matches(".*/br/(fab|err|sts).*"))

Tenga en cuenta que puedo tener mucho más uri y este método se llama muy a menudo.

¿Cuál es la mejor respuesta entre mis elecciones?


Ambos son lo suficientemente rápidos para terminar antes de que te des cuenta. Iría por el que puedes leer más fácilmente.


Espero que el contains() sea ​​más rápido, ya que no tendrá que compilar ni iterar a través de una expresión regular (relativamente) compleja, sino simplemente buscar una secuencia de caracteres.

Pero (como con todas las optimizaciones) debes medir esto. Su situación particular puede afectar los resultados, en mayor o menor grado.

Además, ¿se sabe que esto te está causando dolor (wt. Performance)? Si no, no me preocuparía demasiado y elegiría la solución más adecuada para sus necesidades, independientemente de los problemas de rendimiento. ¡La optimización prematura te causará una cantidad excesiva de dolor si lo dejas!


He hecho una prueba y es más rápido de usar contiene. Como dijo Ewan Todd, ambos son lo suficientemente rápidos como para no molestarse en eso.


Si el bit con el que está tratando de coincidir está siempre al principio o al final, o es de alguna otra forma predecible, entonces: ¡ninguno!

Por ejemplo, si las direcciones URL son como http://example.com/br/fab o http://example.com/br/err todo el tiempo, entonces podría almacenar "br / fab" y "br / err", etc. en un HashSet o similar, y luego se le asigna una URL entrante, corte la última parte del mismo y consulte el Conjunto para ver si lo contiene. Esto se escalará mejor que cualquiera de los métodos que hayas dado (con un HashSet no debería ser más lento buscar entradas, sin importar cuántas haya).

Si necesita coincidir con las subcadenas que aparecen en ubicaciones arbitrarias ... depende de lo que quiere decir con "mucho más". Una cosa que debe hacer independientemente de los detalles del problema es probar las cosas y compararlas.


Si va a utilizar una expresión regular, créela por adelantado y reutilice el mismo objeto de Pattern :

private static final Pattern pattern = Pattern.compile(".*/br/(fab|err|sts).*");

¿Realmente necesitas el ". *" En cada extremo? No esperaría que fuera requerido, si usas Matcher.find() .

¿Cual es mas rápido? La forma más fácil de averiguarlo es medirlo con algunos datos de muestra, con muestras lo más realistas posible. (La solución más rápida puede depender de

¿Ya estás seguro de que esto es un cuello de botella? Si ya ha medido el código lo suficiente como para descubrir que se trata de un cuello de botella, me sorprende que no haya probado ambos. Si no ha verificado que es un problema, es lo primero que debe hacer antes de preocuparse por el "código más rápido posible".

Si no es un cuello de botella, yo personalmente optaría por la versión no regex a menos que sea un adicto a expresiones regulares. Las expresiones regulares son muy poderosas, pero también muy fáciles de equivocarse.


es mucho más rápido si usas indexOf ().

if(uri.indexOf("/br/fab")>-1 || uri.indexOf("/br/err")>-1 || uri.indexOf("/br/sts") >-1 ) { your code. }

y el problema con los contenidos () es internamente, crea un objeto Matcher (java.util.regex.Matcher) y la expresión es evidente.

Matcher es una cosa muy costosa si se procesa una gran cantidad de datos.


ACTUALIZACIÓN: Sé que este no es el mejor código de referencia y para cada caso hay varias formas de optimizarlo.

Lo que quería lograr era que, para un desarrollador regular que usara las formas más simples de hacer las cosas y no es un experto en JVM, esa es la forma "común" de usarlo, así que aquí va.

ORIGINAL:

El siguiente código produjo la siguiente salida

contains took: 70 matches took: 113 matches with pre pattern took: 419

La clase de prueba

public class MatchesTester { public static void main(String[] args) { String typeStr = "Nunc rhoncus odio ac tellus pulvinar, et volutpat sapien aliquet. Nam sed libero nec ex laoreet pretium sed id mi. Aliquam erat volutpat. Aenean at erat vitae massa iaculis mattis. Quisque sagittis massa orci, sit amet vestibulum turpis tempor a. Etiam eget venenatis arcu. Nunc enim augue, pulvinar at nulla ut, pellentesque porta sapien. Maecenas ut erat id nisi tincidunt faucibus eget vel erat. Morbi quis magna et massa pharetra venenatis ut a lacus. Vivamus egestas vitae nulla eget tristique. Praesent consectetur, tellus quis bibendum suscipit, nisl turpis mattis sapien, ultrices mollis leo quam eu eros.application/binaryNunc rhoncus odio ac tellus pulvinar, et volutpat sapien aliquet. Nam sed libero nec ex laoreet pretium sed id mi. Aliquam erat volutpat. Aenean at erat vitae massa iaculis mattis. Quisque sagittis massa orci, sit amet vestibulum turpis tempor a. Etiam eget venenatis arcu. Nunc enim augue, pulvinar at nulla ut, pellentesque porta sapien. Maecenas ut erat id nisi tincidunt faucibus eget vel erat. Morbi quis magna et massa pharetra venenatis ut a lacus. Vivamus egestas vitae nulla eget tristique. Praesent consectetur, tellus quis bibendum suscipit, nisl turpis mattis sapien, ultrices mollis leo quam eu eros."; int timesToTest = 10000; long start = System.currentTimeMillis(); int count = 0; //test contains while(count < timesToTest){ if (typeStr.contains("image") || typeStr.contains("audio") || typeStr.contains("video") || typeStr.contains("application")) { //do something non expensive like creating a simple native var int a = 10; } count++; } long end = System.currentTimeMillis(); System.out.println("contains took: "+ (end - start)); long start2 = System.currentTimeMillis(); count = 0; while(count < timesToTest){ if (typeStr.matches("(image|audio|video|application)")) { //do something non expensive like creating a simple native var int a = 10; } count++; } long end2 = System.currentTimeMillis(); //new var to have the same cost as contains System.out.println("matches took: "+ (end2 - start2)); long start3 = System.currentTimeMillis(); count = 0; Pattern pattern = Pattern.compile("(image|audio|video|application)"); while(count < timesToTest){ if (pattern.matcher(typeStr).find()) { //do something non expensive like creating a simple native var int a = 10; } count++; } long end3 = System.currentTimeMillis(); //new var to have the same cost as contains System.out.println("matches with pre pattern took: "+ (end3 - start3)); }