Recherche «contient» hautes performances dans la liste des chaînes en C #

J’ai une liste d’env. 500 000 chaînes, chacune env. 100 caractères de long. Étant donné un terme de recherche, je souhaite identifier toutes les chaînes de la liste qui contiennent le terme de recherche. Pour le moment, je le fais avec un ancien jeu de données standard en utilisant la méthode Select (“MATCH% term%”). Cela prend environ 600 ms sur mon ordinateur portable. Je voudrais aller plus vite, peut-être 100-200ms.

Quelle serait une approche recommandée?

Les performances sont essentielles pour pouvoir échanger l’empreinte mémoire de meilleures performances si nécessaire (dans des limites raisonnables). La liste des chaînes ne changera pas une fois initialisée, le calcul des hachages serait également une option.

Quelqu’un a-t-il une recommandation et quelles structures de données C # conviennent le mieux à la tâche?

J’ai entendu de bonnes choses sur Lucene.NET lorsqu’il s’agit d’effectuer des recherches rapides en texte intégral. Ils ont fait le nécessaire pour trouver les structures de données les plus rapides et les utiliser. Je suggérerais de tenter le coup.

Sinon, vous pourriez simplement essayer quelque chose comme ceci:

var matches = list.AsParallel().Where(s => s.Contains(searchTerm)).ToList(); 

Mais cela ne vous réduira probablement pas à 100 ms.

Un arbre de sorting ou de suffixe aiderait à rendre cela plus rapide – c’est essentiellement ce que la recherche en texte intégral (généralement) utilise.

Il existe des implémentations en C # que vous pouvez utiliser. Voir également le fil SO: Vous recherchez l’implémentation de l’arborescence de suffixes en C #?

Comme mentionné par @leppie, l’exécution parallèle vous fournira probablement le gain de performances x3 que vous recherchez. Mais là encore, vous devrez mesurer de près, sans que cela devine qui que ce soit.

Avez-vous essayé de charger vos chaînes dans une List , puis d’utiliser la méthode Contains extensions Linq?

 var myList = new List(); //Code to load your list goes here... var searchTerm = "find this"; var match = myList.Contains(searchTerm); 

Avez-vous essayé le suivant?

 list.FindAll(x => x.Contains("YourTerm")).ToList(); 

Pour une raison quelconque, List.AsParallel (). Where (…) est plus lent que list.FindAll (…) sur mon PC.

 list.AsParallel().Where(x => x.Contains("YourTerm")).ToList(); 

J’espère que ceci vous aidera.

 public static bool ContainsFast(this IList list, T item) { return list.IndexOf(item) >= 0; } 

Sur la base des tests que j’ai faits, cette variation de Contains était environ 33% plus rapide de mon côté.

Vous devriez essayer d’utiliser la classe Dictionary. C’est beaucoup plus rapide que List parce que c’est une recherche indexée.

 Dictionary ldapDocument = new Dictionary(); //load your list here //Sample -> ldapDocument.Add("014548787","014548787"); var match = ldapDocument.ContainsKey(ssortingngToMatch);