2009-03-09 10 views
10

Una de mis estructuras de datos favoritas en la universidad fue el Trie. Es una gran estructura de datos para mantener un gran conjunto de cadenas si los prefijos se comparten. Las búsquedas también son agradables, ya que se realizan en O (| longitud |) de la cadena independientemente de cuántas cadenas hay en el conjunto.¿Sigue siendo una buena idea para las arquitecturas modernas?

En comparación, un árbol equilibrado sería O (log N) en el número de elementos establecidos, más lo que pague por las comparaciones. Una tabla hash implicaría el cálculo de hash, comparación, etc.

Me sorprende que there is no Trie implementation in the standard library of most languages.

La única razón por la que se me ocurrió fue la posibilidad de que los costos de acceso a la memoria lo hagan demasiado caro. En lugar de investigar ubicaciones O (log N) si realiza una búsqueda en árbol, no está haciendo O (| longitud |) ubicaciones diferentes, con todas las consecuencias. Si las cuerdas son largas, esto podría terminar siendo demasiado.

Así que me pregunto: ¿cuánto es lo que acabo de describir una preocupación? ¿Qué haces cuando necesitas almacenar un conjunto grande o un mapa de cadenas?

+0

"en la biblioteca estándar de la mayoría de las funciones." ¿quisiste decir "en la biblioteca estándar de la mayoría de los _idiomas_?" –

+0

Si va a publicar preguntas estrechamente relacionadas (http://stackoverflow.com/questions/623892/where-do-i-find-a-standard-trie-based-map-implementation-in-java) debería vincularlos juntos. –

+0

Iba a ir, y luego puso el enlace de Wikipedia para Trie en su lugar ... De todos modos, ahora pones el enlace, así que estamos bien. – Uri

Respuesta

7

No había pensado en esto como un área de preocupación antes, pero ahora que lo menciona, hay momentos en que una implementación estándar de Trie podría ser útil. Por otro lado, hasta donde yo sé, Tries es usado por Python y Perl y otros lenguajes que uso ahora.

La última vez que revisé, que era hace años, el código del kernel BSD usaba Tries (Patricia Tries) en el código para seleccionar la mejor interfaz para enviar paquetes. Parece Wikipedia has some info.

+0

No creo que Python tenga incorporado, ver p. Ej. http://bugs.python.org/issue9520 –

4

Podrías crear dos aplicaciones de muestra y ver cuál funciona mejor. El acceso a la memoria es económico, suponiendo que no se produce un error de página. Entonces es muy caro Para el desarrollo de aplicaciones cliente, casi siempre es mejor procesar que acceder a la memoria por esta misma razón. Los procesadores modernos son ridículamente rápidos, pero las fallas de caché aún duelen.

+0

Solía ​​trabajar en Intel durante varios años, así que estoy extremadamente paranoico incluso cuando me salgo de la misma línea de caché. Además, si cada nodo está ubicado en otra parte del montón, a menos que mi recolector de basura esté reorganizando cosas, es muy posible que haya un error de página. – Uri

+1

¡Buena suerte escribiendo cualquier algoritmo de búsqueda que permanezca en la misma línea de caché! –

+0

Una vez hice eso con gráficos fijos para divertirme (creo que en los mapas del metro) y obtuve una aceleración impresionante ... :) – Uri

2

Hice algunas pruebas de rendimiento en C# con un Trie y un diccionario (una tabla hash fuertemente tipada). Encontré que el diccionario era 5-10 veces más rápido que el Trie. Tal vez mi implementación del Trie podría optimizarse un poco, pero apenas lo suficiente como para ser mucho más rápido que (o incluso tan rápido) como el Diccionario. El método ContainsKey en el diccionario está cerca de una operación O (1) (dependiendo de qué tan bueno sea el algoritmo hash), por lo que no es fácil crear una colección que supere eso siempre que el algoritmo hash sea razonablemente rápido. .

Con un IEqualityComparer personalizado puede usar casi cualquier cosa como clave en un Diccionario, lo que lo hace bastante flexible. Un Trie es un poco más limitado en lo que puedes usar como clave, por lo que limita un poco la utilidad.

+3

Por supuesto, el hash tiene un acceso más rápido. La ventaja de un trie sobre un hash es la eficiencia de la memoria. – Frank

+0

@Frank Dictionary: almacene cada cuerda con poca sobrecarga. Trie: almacene letras comunes una vez pero con una sobrecarga de asignar un objeto con al menos dos punteros (a la izquierda del niño, a la izquierda del niño). Conclusión: Al menos en C#, el diccionario es mucho más eficiente en términos de espacio. Hablo desde una triste experiencia triste. –

Cuestiones relacionadas