62 votes

Linq Count () est-il plus rapide ou plus lent que List.Count ou Array.Length?

La méthode Linq Count( ) est-elle plus rapide ou plus lente que List<>.Count ou Array.Length ?

75voto

JaredPar Points 333733

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.

28voto

Marc Gravell Points 482669

La méthode Enumerable.Count() vérifie ICollection<T> , en utilisant .Count - de sorte que dans le cas des tableaux et des listes, elle n’est pas beaucoup plus inefficace (juste un niveau supplémentaire d’indirection ).

25voto

Sam Saffron Points 56236

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

4voto

Jose Points 4227

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.

3voto

Jake Pearson Points 9657

Je crois que si vous appelez Linq.Count () sur un ICollection ou un IList (comme un ArrayList ou une List), il renverra simplement la valeur de la propriété Count. La performance sera donc à peu près la même sur les collections simples.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X