Ir al contenido principal

Algoritmo Boyer, Moore, Horspool, Raita vrs java.lang.String.contains

En mi paso por la Universidad, entre los cursos de Licenciatura tuve la suerte de llevar el curso de Recuperación de Información (RI), con el prof. Edgar Casasola.

A continuación un extracto del correo, que recientemente le escribí comentandole una cuestión acerca de la comparación de los algoritmos Boyer, Moore, Horspool, Raita vrs java.lang.String.contains; los resultado a la luz de mi pequeño estudio, arrojaron que el "perfomance" para buscar al menos una ocurrencia de texto dentro de otro, del objeto de Java resulta mas eficiente que las técnicas RI, mas elaboradas.

---------------*-----------------------------*--------------------------
.....

Para comentarle el contexto; Actualmente trabajo para la compañía avVenta en Costa Rica y como parte de un proyecto para uno de sus clientes, existía una implementación que toma un archivo con palabras vulgares o obscenas y realiza una búsqueda a fuerza bruta (O(n)), recorriendo todas las palabras hasta encontrar la ocurrencia de una de las palabras en el texto, el pseudo-stremmer que tiene este algoritmo, consiste en agregar palabras sobre el corpus de las obscenidades, pero cambiando por ejemplo las “o” por un “0” (cero), o la “a” por un (4), etc.

 

Me pregunte que desempeño tendría esta implementación contra la búsqueda vectorial y contra algoritmos de búsqueda de texto dentro de texto.

 

Además de un algoritmo “custom” que el cliente me facilito (valga decir que es el mas deficiente a nivel de resultados, sin embargo vale resaltar, el mismo tiene “stremmers” para diferentes lenguajes y soporte para búsqueda i18n), también hice una prueba con Apache Lucene (la implementación de un buscador vectorial Open de Apache, http://lucene.apache.org/java/docs/index.html), utilizando un Índice invertido en memoria, además utilice el algoritmo, que según leí es mas rápido de esta biblioteca (http://johannburkard.de/software/stringsearch/), el cual se basa en un hibrido de Boyer, Moore, Horspool, Raita, los resultados en milisegundos y orden descendiente los comparto a continuación.

 

{203=implementación basada en java.lang.String.contains (indexOf > -1)

 2266=implementación basada en Apache Lucene

 2312=implementacion basada en el stringsearch (http://johannburkard.de/software/stringsearch/),

 11406=obscenityProfanityFilter, este fue un algoritmo propietario que me pasaron, el mismo que tiene los stremmer.

}

 

Valga decir que hice otros “Junit” (pruebillas de unidad) para determinar que la funcionalidad de los algoritmos fuera idéntica y en efecto, todos funcionan de la manera esperada.

 

Dudoso con los resultados, fui curioso e implemente el siguiente código:

 

String text = "Hello folkes jiji opa oop upa lupa as and tropes and listes and shomis and tepos";

              String wordToSearch = "shomis";

              int loop = 2000;

              long millins = 0;

              long totalElapse = 0;

              int hit = 0;

              StringSearch so = new BoyerMooreHorspoolRaita();

 

              millins = System.currentTimeMillis();

              for (int i = 0; i <>

 

                     if (text.contains(wordToSearch)) {

 

                           hit += 1;

                     }

              }

 

              wordToSearch = "upalupa";

 

              for (int i = 0; i <>

 

                     if (text.contains(wordToSearch)) {

 

                           hit += 1;

                     }

              }

 

              totalElapse = System.currentTimeMillis() - millins;

 

              System.out.println("Contains algo: " + totalElapse);

              System.out.println(hit + " = " + loop);

 

              // **********************

              // **********************

              // **********************        

 

              hit = 0;

              wordToSearch = "shomis";

             

              millins = System.currentTimeMillis();          

              for (int i = 0; i <>

 

                     if (so.searchString(text, wordToSearch)!= -1) {

 

                           hit += 1;

                     }

              }

             

              wordToSearch = "upalupa";

 

              for (int i = 0; i <>

 

                     if (so.searchString(text, wordToSearch)!= -1) {

 

                           hit += 1;

                     }

              }

              totalElapse = System.currentTimeMillis() - millins;

 

              System.out.println("StringSearch algo: " + totalElapse);

              System.out.println(hit + " = " + loop);

 

El resultado:

 

Contains algo: 0

2000 = 2000

StringSearch algo: 15

2000 = 2000

 

Dejando de lado que la implementación de StringSearch permite utilizar “wildcard” y que quizá funcione mejor en colecciones grandes (esto es un supuesto), me pareció interesante compartir estos resultados con alguien que esta mas comprometido con el tema, como comprenderá el mercado nacional, nos proporciona poco espacio para jugar con este tipo de cosas muy interesantes y el conocimiento que no se refresca tienen a marchitarse un poco (lo cual es una pena).

......

Comentarios

Entradas más populares de este blog

Pasos para remover Postgresql 8.3 en MAC OS

Tomado de: http://forums.enterprisedb.com/posts/list/1437.page In Mac OSX: (Assuming Default Locations) Via uninstaller: 1) In the installation directory, there will be a uninstall-postgresql.app file will be there, executing (double clicking) that will uninstall the postgresql installation. Manual Uninstallation: 1) Stop the server sudo /sbin/SystemStarter stop postgresql-8.3 2) Remove menu shortcuts: sudo rm -rf /Applications/PostgreSQL 8.3 3) Remove the ini file sudo rm -rf /etc/postgres-reg.ini 4) Removing Startup Items sudo rm -rf /Library/StartupItems/postgresql-8.3 5) Remove the data and installed files sudo rm -rf /Library/PostgreSQL/8.3 6) Delete the user postgres sudo dscl . delete /users/postgres

Validaciones con HTML5 sin necesidad de form.submit

Como parte de HTML5 existe la posibilidad de agregar información a los inputs de un form, para realizar validaciones; podemos indicar si queremos que sea requerido, con el tipo de datos; number, email, etc restringimos los valores que pueden ser agregados, podemos usar alguna mascara para validaciones, colocar mensajes de error custom, etc (en la red existen muchos ejemplos acerca de como customizar formularios). Ahora bien pongamos en contexto, tengo un formulario como este: <form name="managerForm"  id="managerForm">              <p>                  Name:                 <input id="managerNameText" required="required" placeholder="Write here the new manager name" size="40"/>              </p>             <p>                 Email:                 <input id="emailText" required="required" placeholder="myemail@myserver.com" type="email" />

Inventario anual de bebidas

Hola gente, Solo quería compartir mi inventario anual de bebidas (así conocer gustos), excluyendo algunas cervecillas que tengo por ahí guardadas, este es mi inventario: Ron: Flor de Cana 1 botella 5 anos. 2 botellas 7 anos una pacha 7 anos 2 botellas 12 anos 1 botella 18 anos Ron Zacapa 15 anos Centenario pachita 7 anos Centanario pachita 12 anos Bacardi limon Bacardi Razz Ron abuelo 7 anos Bacardi superior 1862 Ron Boltran XL Ron Centenario Garrafon Ron Jamaica Appleton 7 anos Ron Jamaica Appleton 12 anos (muchisimas gracias a Mayra :) Capitan Morgan Rum Jumbie, coconnut splash Ron coconut Malibu Ron Tequila Milagro Silver (muchisimas gracias a Pablito :) Sauza Gold Sauza Reposado Don Julio Reposado Vino Luigi Borer Malbec 2006 Casillero del Diablo, Caberut Sauviguon 2009 Vodka 2 botellas smirnoff y una smirnoff con sabor cranberry Cremas y otro licores Cahuita pacha Amaretto Barinet Licor de menta Licor de agave Rancho Escondido Bayleys 2 botellas (muchisimas gracias a Brian B :) Li