none
Eficiencia sentencias LINQ RRS feed

  • Pregunta

  • Hola,

    Hace dias que me corre por la cabeza un tema de eficiencia interna de las consultas LINQ. Parece una tonteria pero en segun que casos podria ser importante segun lo que me digan.

    El caso es tengo tres tipos de sentencia donde me interesaria saber que es más eficiente.

    lista.Where(p=> p).Any()
    lista.Where(p=> p).Count() > 0
    lista.Any(p=> p)

    A mi modo de parecer la última sentencia seria la más eficiente y algo dicen en este enlace (http://stackoverflow.com/questions/5741617/listt-any-or-count) pero hay diferencia con la primera sentencia?

    Entiendo que en cualquier caso sera lo mismo para Single, First, FirstOrDefault,... 

    Alguien que tenga experiencia en esto me puede decir si noto diferencias o solo es un efecto placebo? 

    Gracias.


    Vota mi respuesta si te ha sido útil. Gracias.

    martes, 15 de mayo de 2012 8:10

Todas las respuestas

  • hola

    cuando dices linq, te refiere a linq to object o linq to SQL ? porque es distinto como aplcia en eficiencia si trabjas solo con objecto a que si lo haces contra una db, en donde el linq que crees se traduce en una query sql

    desde mi punto de visto, yo hubiera implementado la ultima opcion

    lista.Any(p=> p)

    porque en las otras dos estas realizando un paso de mas obteniendo la entidad para despues validar si existe o si cuenta algun valor, con el Any() directo se hace en un unico paso

    igualmente algo que no has clarado es de que tipo es "p", proque alli no veo que definas ninguna condicion de filtro

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    martes, 15 de mayo de 2012 12:15
  • Daria igual el tipo de "p", puesto que lo que queria reflejar era el tema de poner una condición para filtrar la colección.

    Entonces Leandro, segun comentas en LinqToSql y LinqToEntities seria diferente cada sentencia? Yo tenia entendido que un IEnumerable hasta que no haces un ToList u otro metodo ejecutor no se ejecuta, entonces claro mi duda era si al ejecutar el compilador optimiza la sentencia y las sentencias 1 y 3 serian lo mismo para el.

    Con que me respondais esta ultima cuestion es suficiente.

    Gracias


    Vota mi respuesta si te ha sido útil. Gracias.

    martes, 15 de mayo de 2012 12:40
  • segun comentas en LinqToSql y LinqToEntities seria diferente cada sentencia?

    seguramente cada uno de estos linq se reflejaria en linq to sql o EF de forma diferente, porque la Expression generada y mapeada a SQL seguro cambie

    la forma de validarlo es poniendo el profiler de sql y lanzar cada opcion para ver que query genera cada caso

    pero seguro sean diferentes

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina

    martes, 15 de mayo de 2012 15:08
  • Hola.

    Pues la más rapida es Any() o Any(TSource) para esto que deseas o no la mas rapida si no la más directa.

    El hecho de preguntar por .Count() [Ojo! .Count NO .Count(TSource)] pese a que es un extensor de IEnumerable<T> implica un casteo a ICollection<T> donde si se logra hacer el casteo [Que la verdad NO SE en que casos no se pueda hacer, teniendo presente que es un extensor de IEnumerable<T> y que ICollection<T> implementa de IEnumerable<T> y de IEnumerable] se retorna la propiedad Count de esta, Si no se logra hacer el casteo Count acudira al Enumerator de la coleccion y recorrera uno a uno los items llevando la suma de estos.

    Osea hace algo como:

                ICollection<string> collection = lista;
                int cantidad = collection.Count;

    Si acudes a Any() este siempre acudira al Enumerator de la coleccion y simplemente preguntara por el valor bool del metodo MoveNext(). Algo así:

                bool contieneElementos;
                using (IEnumerator<string> enumerador = lista.GetEnumerator())
                {
                    if (enumerador.MoveNext())
                    {
                        contieneElementos = true;
                    }
                }

    Como te digo, me "parece" mas rapido el casteo de Count, pero corres el riesgo de que no se logre y se haga ese conteo "maual", ademas de que del lado de la Linq preguntes por > 0 :S ... más bien tirale de una vez a Any() :D

    Saludos.


    Nicolás Herrera
    Bogotá - Colombia
    BLOG - Leader Group BogotaDotNet
    "Daría todo lo que sé, por la mitad de lo que ignoro." Rene Descartes

    domingo, 20 de mayo de 2012 3:41