Je regarde une liste générique pour trouver des articles basés sur un certain paramètre.
En général, quelle serait la mise en œuvre la meilleure et la plus rapide?
1. Parcourez chaque élément de la liste, enregistrez chaque match dans une nouvelle liste et renvoyez-le.
foreach(string s in list)
{
if(s == "match")
{
newList.Add(s);
}
}
return newList;
Ou
2. Utilisation de la méthode FindAll et transmission d'un délégué.
newList = list.FindAll(delegate(string s){return s == "match";});
Est-ce qu'ils ne courent pas tous les deux en ~ O (N)? Quelle serait la meilleure pratique ici?
Cordialement, Jonathan
Vous devez absolument utiliser la méthode FindAll
ou la méthode LINQ équivalente. Pensez également à utiliser le lambda plus concis à la place de votre délégué si vous le pouvez (nécessite C # 3.0):
var list = new List<string>();
var newList = list.FindAll(s => s.Equals("match"));
Jonathan,
Vous trouverez une bonne réponse à cette question au chapitre 5 (Considérations sur les performances) de Linq To Action .
Ils mesurent a pour chaque recherche qui s’exécute environ 50 fois et qui aboutit avec foreach = 68ms par cycle/List.FindAll = 62ms par cycle En réalité, il serait probablement dans votre intérêt de simplement créer un test et de constater par vous-même.
List.FindAll est O(n) et va parcourir toute la liste.
Si vous souhaitez exécuter votre propre itérateur avec foreach, je vous recommande d'utiliser l'instruction de rendement et de renvoyer un IEnumerable si possible. De cette façon, si vous n'avez plus besoin que d'un élément de votre collection, ce sera plus rapide (vous pouvez arrêter votre appelant sans épuiser toute la collection).
Sinon, restez sur l'interface BCL.
Toute différence de performance va être extrêmement mineure. Je suggérerais FindAll pour la clarté, ou, si possible, Enumerable.Where. Je préfère utiliser les méthodes Enumerable car elles permettent une plus grande flexibilité dans la refactorisation du code (vous ne prenez pas de dépendance sur List<T>
).
Oui, les deux implémentations sont O (n). Ils doivent examiner chaque élément de la liste pour trouver toutes les correspondances. En termes de lisibilité, je préférerais aussi FindAll. Pour des considérations sur les performances, consultez LINQ en action (Chapitre 5.3). Si vous utilisez C # 3.0, vous pouvez également appliquer une expression lambda. Mais ce n'est que la cerise sur le gâteau:
var newList = aList.FindAll(s => s == "match");
Je suis avec les Lambdas
List<String> newList = list.FindAll(s => s.Equals("match"));
À moins que l'équipe C # n'ait amélioré les performances de LINQ
et FindAll
, l'article suivant semble suggérer que for
et foreach
surpasseraient LINQ
et FindAll
lors de l'énumération d'objets: LINQ on Object Performance .
Cet article a été publié en mars 2009, juste avant que ce poste ne soit initialement demandé.