2009-03-09 15 views
10

L'une de mes structures de données préférées à l'université était le Trie. C'est une excellente structure de données pour conserver un grand nombre de chaînes si les préfixes sont partagés. Les recherches sont également intéressantes, puisqu'elles sont faites à O (| longueur |) de la chaîne indépendamment du nombre de chaînes présentes dans l'ensemble. En comparaison, un arbre équilibré serait O (log N) dans le nombre d'éléments définis, plus tout ce que vous payez pour les comparaisons. Une table de hachage impliquerait le calcul de hachage, la comparaison, etc.Les essais sont-ils toujours une bonne idée sur les architectures modernes?

Il est donc surprenant pour moi que there is no Trie implementation in the standard library of most languages. La seule raison pour laquelle je suis arrivé à la conclusion était la possibilité que les coûts d'accès à la mémoire le rendent trop cher. Plutôt que d'enquêter sur les emplacements O (log N) si vous effectuez une recherche arborescente, vous ne faites pas O (| longueur |) emplacements différents, avec toutes les conséquences. Si les cordes sont longues, cela pourrait être trop lourd.

Donc je me demande: combien est ce que je viens de décrire une préoccupation? Que faites-vous lorsque vous avez besoin de stocker un grand ensemble ou une carte de chaînes?

+0

"dans la bibliothèque standard de la plupart des fonctions." Voulez-vous dire "dans la bibliothèque standard de la plupart des langages?" –

+0

Si vous allez poster des questions connexes (http://stackoverflow.com/questions/623892/where-do-i-find-a-standard-trie-based-map-implementation-in-java) vous devriez reliez-les ensemble. –

+0

J'allais à, et ensuite mettre le lien Wikipedia pour Trie à la place ... Quoi qu'il en soit, maintenant vous mettez le lien, alors nous sommes bons. – Uri

Répondre

7

Je n'avais pas pensé à cela comme un sujet de préoccupation avant, mais maintenant que vous le mentionnez, il y a des moments où une implémentation standard de Trie pourrait être utile. D'un autre côté, autant que je sache, les Tries sont utilisés par Python et Perl et d'autres langages à cordes que j'utilise maintenant.

Dernière vérification, il y a longtemps, le code du noyau BSD utilisait Tries (Patricia Tries) dans le code pour sélectionner la meilleure interface pour l'envoi de paquets. Ressemble à Wikipedia has some info.

+0

Je ne pense pas que Python a été intégré, voir par exemple. http://bugs.python.org/issue9520 –

4

Vous pouvez simplement créer deux exemples d'applications et voir lequel fonctionne le mieux. L'accès à la mémoire est bon marché en supposant que vous n'avez pas de défaut de page. Alors c'est très cher. Pour le développement d'applications client, il est presque toujours préférable de traiter que d'accéder à la mémoire pour cette raison. Les processeurs modernes sont ridiculement rapides, mais les échecs de cache font encore mal.

+0

Je travaillais chez Intel depuis plusieurs années, donc je suis extrêmement paranoïaque même si je ne suis plus dans la même ligne de cache. En outre, si chaque nœud est situé ailleurs sur le tas, à moins que mon garbage collector ne réorganise des choses, je peux très bien faire une erreur de page. – Uri

+1

Bonne chance pour écrire tout algorithme de recherche qui reste dans la même ligne de cache! –

+0

Je l'ai fait une fois avec des graphiques fixes pour le plaisir (pensez cartes de métro) et a obtenu une accélération impressionnante ... :) – Uri

2

J'ai effectué quelques tests de performance en C# avec un Trie et un Dictionary (une table de hachage fortement typée). J'ai trouvé que le dictionnaire était 5-10 fois plus rapide que le Trie. Peut-être que ma mise en œuvre de la Trie pourrait être optimisée un peu, mais à peine suffisante pour être beaucoup plus rapide que (ou peut-être même aussi rapide que) le dictionnaire. La méthode ContainsKey dans le dictionnaire est proche d'une opération O (1) (selon la qualité de l'algorithme de hachage), il n'est donc pas facile de faire une collection qui bat aussi longtemps que l'algorithme de hachage est raisonnablement rapide .

Avec un IEqualityComparer personnalisé, vous pouvez utiliser la plupart des éléments comme clé dans un dictionnaire, ce qui le rend plutôt flexible. Un Trie est un peu plus limité dans ce que vous pouvez utiliser comme clé, ce qui limite quelque peu l'utilité.

+3

Bien sûr, le hachage a un accès plus rapide. L'avantage d'un trie sur un hachage est l'efficacité de la mémoire. – Frank

+0

@Frank Dictionary: stocker chaque chaîne avec peu de frais généraux. Trie: stocke les lettres communes une fois mais avec un overhead d'allocation d'un objet avec au moins deux pointeurs (left neighboor, leftmost child). Conclusion: En C# au moins, le dictionnaire est beaucoup plus efficace en termes d'espace. Je parle d'une triste expérience triste. –