La méthode Linq Count(
) est-elle plus rapide ou plus lente que List<>.Count
ou Array.Length
?
Réponses
Trop de publicités?En général plus Lent. LINQ est Compter, en général, est une O(N)
d'opération en List.Count
et Array.Length
sont à la fois garantis O(1)
.
Cependant il certains cas, LINQ sera spécial, la IEnumerable<T>
paramètre par moulage à certains types d'interfaces telles que IList<T>
ou ICollection<T>
. Il utilisera alors que le Comte méthode pour faire une réelle Count()
de l'opération. Donc, il va redescendre à O(1)
. Mais vous payez toujours le mineur généraux de la distribution et de l'interface d'appel.
Marc a le droit de réponse, mais le diable est dans le détail.
Sur ma machine:
- Pour les tableaux .La longueur est d'environ 100 fois plus rapide que .Count()
- Pour Les Listes .Le comte est environ 10 fois plus rapide que .Count() - Remarque: je pense à des performances similaires, de toutes les Collections de mettre en œuvre
IList<T>
Les tableaux de commencer plus lent depuis .La longueur ne comporte qu'une seule opération .Compter sur les tableaux comporte une couche d'indirection. Donc .Compter sur des tableaux commence 10x plus lent (sur ma machine), ce qui pourrait être l'une de ces raisons, l'interface est implémentée de manière explicite. Imaginez si vous aviez un objet avec les deux propriétés publiques, .Le comte et .Longueur. Les deux font exactement la même chose, mais .Le comte est 10X plus lent.
Bien sûr, non de ce qui fait vraiment une grande différence, puisque vous aurez à faire le compte de vos tableaux et des listes de millions de fois par seconde à se sentir un gain de performance.
Code:
static void TimeAction(string description, int times, Action func) {
var watch = new Stopwatch();
watch.Start();
for (int i = 0; i < times; i++) {
func();
}
watch.Stop();
Console.Write(description);
Console.WriteLine(" Time Elapsed {0} ms", watch.ElapsedMilliseconds);
}
static void Main(string[] args) {
var array = Enumerable.Range(0, 10000000).ToArray();
var list = Enumerable.Range(0, 10000000).ToArray().ToList();
// jit
TimeAction("Ignore and jit", 1 ,() =>
{
var junk = array.Length;
var junk2 = list.Count;
array.Count();
list.Count();
});
TimeAction("Array Length", 1000000, () => {
var tmp1 = array.Length;
});
TimeAction("Array Count()", 1000000, () =>
{
var tmp2 = array.Count();
});
TimeAction("Array Length through cast", 1000000, () =>
{
var tmp3 = (array as ICollection<int>).Count;
});
TimeAction("List Count", 1000000, () =>
{
var tmp1 = list.Count;
});
TimeAction("List Count()", 1000000, () =>
{
var tmp2 = list.Count();
});
Console.ReadKey();
}
Résultats:
Longueur du tableau, le Temps Écoulé 3 ms Tableau Count() Temps Écoulé 264 ms Longueur du tableau par le biais de fonte Temps Écoulé 16 ms Liste de Compter le Temps Écoulé 3 ms Liste Count() Temps Écoulé 18 ms
Je dirais que cela dépend de la liste. Si c'est un IQueryable qui est une table dans une base de données quelque part, Count () sera beaucoup plus rapide car il n'a pas à charger tous les objets. Mais si la liste est en mémoire, j'imagine que la propriété Count serait plus rapide, sinon plus, identique.