Il semblerait que ce qui suit puisse être vrai :
- Vos clés sont des chaînes de caractères.
- Les insertions se font une seule fois.
- Les recherches sont fréquentes.
- Le nombre de paires clé-valeur est relativement faible (disons, moins d'un K ou ainsi).
Dans ce cas, vous pourriez envisager une liste triée par rapport à ces autres structures. Cela sera moins performant que les autres lors des insertions, car une liste triée est en O(N) lors de l'insertion, par rapport à O(1) pour une liste chaînée ou une table de hachage, et O(log2N) pour un arbre binaire équilibré. Mais les recherches dans une liste triée peuvent être plus rapides que dans ces autres structures (je vais l'expliquer bientôt), donc vous pourriez vous en sortir. De plus, si vous effectuez toutes vos insertions en une fois (ou si vous n'avez pas besoin de recherches avant que toutes les insertions soient terminées), alors vous pouvez simplifier les insertions en O(1) et faire un tri beaucoup plus rapide à la fin. De plus, une liste triée utilise moins de mémoire que ces autres structures, mais cela n'aura probablement d'importance que si vous avez de nombreuses petites listes. Si vous avez une ou quelques grandes listes, alors une table de hachage est susceptible de mieux fonctionner qu'une liste triée.
Pourquoi les recherches pourraient-elles être plus rapides avec une liste triée? Eh bien, il est clair que c'est plus rapide qu'une liste chaînée, avec le temps de recherche en O(N) de cette dernière. Avec un arbre binaire, les recherches ne restent en O(log2N) que si l'arbre reste parfaitement équilibré. Garder l'arbre équilibré (rouge-noir, par exemple) ajoute à la complexité et au temps d'insertion. De plus, avec les listes chaînées et les arbres binaires, chaque élément est un1 nœud séparément alloué, ce qui signifie que vous devrez déréférencer des pointeurs et probablement accéder à des adresses mémoire potentiellement très éloignées, augmentant les chances de manquer le cache.
En ce qui concerne les tables de hachage, vous devriez probablement lire quelques autres questions ici sur StackOverflow, mais les principaux points d'intérêt sont les suivants :
- Une table de hachage peut dégénérer en O(N) dans le pire cas.
- Le coût du hachage n'est pas nul, et dans certaines implémentations, il peut être significatif, en particulier dans le cas des chaînes de caractères.
- Comme dans les listes chaînées et les arbres binaires, chaque entrée est un nœud stockant plus que juste la clé et la valeur, également séparément allouée dans certaines implémentations, donc vous utilisez plus de mémoire et augmentez les chances de manquer le cache.
Bien sûr, si vous vous préoccupez vraiment de la performance de l'une de ces structures de données, vous devriez les tester. Vous ne devriez avoir aucun problème à trouver de bonnes implémentations de chacune d'entre elles pour la plupart des langages courants. Il ne devrait pas être trop difficile de mettre quelques-unes de vos données réelles dans chacune de ces structures de données et de voir laquelle se comporte le mieux.
- Il est possible qu'une implémentation pré-alloue un tableau de nœuds, ce qui aiderait à résoudre le problème de cache. Je n'ai pas vu cela dans une vraie implémentation de listes chaînées ou d'arbres binaires (bien sûr, je n'ai pas tout vu), bien que vous puissiez certainement le faire vous-même. Vous auriez toujours une possibilité légèrement plus élevée de manquer le cache, cependant, puisque les objets <em>nœud</em> seraient nécessairement plus grands que les paires clé/valeur.