J'ai besoin d'itérer et de compter. Quel est le plus rapide ou préféré: ToArray () ou ToList ()? [dupliquer]
-
22-07-2019 - |
Question
Double possible:
Est-il préférable d'appeler ToList () ou ToArray () dans les requêtes LINQ?
J'ai un code comme celui-ci:
void Foobar(string[] arr, Dictionary<string, string[]>)
{
var t = arr.Intersect(dic.Keys).ToList(); // .or ToArray() ?
foreach(var item in t)
{
..
}
var j = t.Count; // also I need this
}
quelle méthode est préférée?
Je pourrais m'en passer, mais j'ai besoin de connaître la taille et je ne veux pas appeler Enumerable.Count<T>()
. Il semble que vous fassiez plus d'actions que Array<T>.Size
ou List<T>.Count
. Ai-je raison?
La solution
En fait, dans l'implémentation actuelle de Count (IEnumerable) dans MS, il existe un raccourci indiquant si IEnumerable est un ICollection et appelle Count à ce sujet. La performance doit donc être comparable pour le comptage des éléments.
ToList et ToArray sont un peu les mêmes. Si IEnumerable est une ICollection, la méthode CopyTo est appelée à la place, ce qui est un peu plus rapide.
Alors, choisissez ce qui rend votre code le plus lisible et testez votre cas d'utilisation pour obtenir une réponse définitive.
Mise à jour: J'ai fait un repère naïf.
À partir d'un tableau: var items = Enumerable.Range(1,1000).ToArray();
- appelant ToList (): 25ms / 10000
- appelant ToArray (): 23 ms / 10000
Commençant par un IEnumerable: var items = Enumerable.Range(1,1000);
- appelant ToList (): 168ms / 10000
- appelant ToArray (): 171 ms / 10000
Donc, fondamentalement, vous obtenez des performances comparables.
Autres conseils
Si vous êtes vraiment préoccupé par les performances, vous devez parcourir le IEnumerable
et le compter au fur et à mesure. Cela évite de devoir créer une nouvelle collection et l'intersection ne doit être itérée qu'une seule fois:
void Foobar(string[] arr, Dictionary<string, string[]>)
{
var t = arr.Intersect(dic.Keys);
int count = 0;
foreach(var item in t)
{
count++;
..
}
var j = count;
}
Mais comme quelqu'un d'autre l'a dit: cela sent la micro-optimisation. Si les performances comptent vraiment dans cette situation, effectuez au moins un profilage des performances afin de déterminer la méthode réellement la plus rapide pour vous.
La différence est probablement si minime qu'il vaut mieux utiliser la méthode qui répond le mieux à vos besoins. Odeurs de micro-optimisation.
Et dans ce cas, puisque tout ce que vous faites est d’énumérer l’ensemble et de compter l’ensemble (vous pouvez le faire avec un IEnumerable), pourquoi ne pas le laisser comme un IEnumerable < > ;?