Loading
PauloHDSousa - Desenvolvedor, Leitor e jogador: Diferença entre Count e Count()

terça-feira, 18 de março de 2014

Diferença entre Count e Count()



Usando o código abaixo como exemplo

List<string> itens = new List<string> {"Paulo", "Henrique","Sousa"}

Quando você chama itens.Count , você vai pegar o valor da propriedade  da própria lista (classe List) que diz a quantidade de itens que ela possui.

Quando você chama itens.Count(), você vai rodar o código que foi implementado pelo objeto que herda IEnumerable.

Tanto o método quanto a propriedade vão retornar o mesmo resultado, a diferença é que o método pode demorar um pouco mais.

Então por que existe o método Count()?

Count()  é um método do  que todos que implementarem a interface IEnumerable vão possuir.
Lembrando que a PROPRIEDADE [Count] vem de List e o método [Count()] vem da implementação de IEnumerable.

No exemplo que utilizei:

List<string> itens; 

A propriedade Count está presente, já se eu tivesse feito:

string[] itens;

Não temos a propriedade Count, em compensação temos a propriedade Length


E como Array implementa IEnumerable também temos o método Count();

O mesmo comportamento do Array acontece na classe System.String, tem a propriedade Lenght da própria classe e uma implementação do método Count()

Conclusão

Devemos sempre usar as propriedades da propriedades que definem o tamanho/quantidade de itens no lugar de chamar o método Count(), ele só deve ser utilizado em casos onde não temos a propriedade, como por exemplo um:

IQueryable<string> itens;

“Lembrando que o método Count() é uma implementação de um método da interface IEnumerable, o que acontece  de código na chamada dele em um objeto Array, String, List, etc... Pode ser diferente de um objeto para outro” 

 Caso queiram dar uma olhada, site com o código fonte do .net http://referencesource.microsoft.com/

 

Update 20/03/2014: (Obrigado Marcos Silva)


Mesmo que o método Count()  implementado pela classe leia da  campo Count, ele ( o método ) ainda vai ser mais lento.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;

namespace NullOrEmpty {
    class Program {

        public static int count { get; set; }
        static List<string> objetos = new List<string>();

        public static void Adicionar(string item) {
            objetos.Add(item);
            count++;
        }
        //Mesma propriedade como método
        public static int CountB() {
            return count;
        }

        static void Main(string[] args) {

            for (int i = 0; i < 100; i++)
                Adicionar(i.ToString());

            Stopwatch sw1 = new Stopwatch();
            Stopwatch sw2 = new Stopwatch();

            //A
            sw1.Start();
            int t1;
            for (int i = 0; i < 9999999; i++)
                t1 = count;
            sw1.Stop();


            //B
            sw2.Start();
            int t2;
            for (int p = 0; p < 9999999; p++)
                t2 = CountB();
            sw2.Stop();

            TimeSpan ts1 = sw1.Elapsed;
            TimeSpan ts2 = sw2.Elapsed;
        }
    }
}

Código //A que lê direto do campo é quase 2x mais rápido do que o código //B que chama um método que lê do campo, mas isso já era esperado por mim.

Nenhum comentário: