none
Rendimiento Linq RRS feed

  • Pregunta

  • Hola, tengo un problema de rendimiento en una consulta Linq.

    Pasa que tengo un objeto (llamado A) que tiene 4 propiedades int que me representar montos por categoria. Luego tengo una Lista (IEnumerable<A> listaA) que contiene a mis objetos A. Actualmente esta lista tiene un maximo de 101 registros.

    La operacion que necesito realizar es sacar el promedio de estas 4 categorias.

    Lo estoy haciendo con un foreach:

    foreach(A objetoA in listaA)
    
    
    
    {
    
    
    
    categoriaA+= objetoA.CategoriaA;
    
    
    
    categoriaB+= objetoA.CategoriaB;
    
    
    
    categoriaC+= objetoA.CategoriaC;
    
    
    
    categoriaD+= objetoA.CategoriaD;
    
    
    
    }
    
    
    
    

    Y esta operacion se demora 2 segundos, eso para mi es mucho tiempo, ya que en el mismo programa con listas mas grandes y "operaciones linq mas complejas" todo pasa mas rapido.

    Mientras tanto con Linq realizo lo siguiente y se demora 10 segundos.

    categoriaA+= (from obj in listaA select obj.CategoriaA).Sum();
    
    
    
    categoriaB+= (from obj in listaA select obj.CategoriaB).Sum();
    
    
    
    categoriaC+= (from obj in listaA select obj.CategoriaC).Sum();
    
    
    
    categoriaD+= (from obj in listaA select obj.CategoriaD).Sum();
    
    
    
    

    Mi clase "A" hereda de otra clase que tambien es "sencilla" solo tiene un entero, dos enums.

    Ojala me puedan ayudar ya que no entiendo el por qué la demora.

    Otra cosa, ¿como puedo medir el rendimiento o tiempo de ejecucion de mis consultas,? hasta ahora empleo un objeto Stopwatch para medir el tiempo que tardan las consultas.

    Gracias.

    jueves, 10 de febrero de 2011 2:21

Todas las respuestas

  • hola

    no se si mejorar, peor no has probado algo asi

     

     public class Categorias
            {
                public int CategoriaA { get; set; }
                public int CategoriaB { get; set; }
                public int CategoriaC { get; set; }
                public int CategoriaD { get; set; }
            }

            public class A
            {
                public int CategoriaA { get; set; }
                public int CategoriaB { get; set; }
                public int CategoriaC { get; set; }
                public int CategoriaD { get; set; }
            }


            private void button1_Click(object sender, EventArgs e)
            {

                List<Categorias> listaA = new List<Categorias>();

                //aqui se cargaria la listaA

                A result = new A();

                result.CategoriaA = listaA.Sum(o => o.CategoriaA);
                result.CategoriaB = listaA.Sum(o => o.CategoriaB);
                result.CategoriaC = listaA.Sum(o => o.CategoriaC);
                result.CategoriaD = listaA.Sum(o => o.CategoriaD);

            }

     

    ¿como puedo medir el rendimiento o tiempo de ejecucion de mis consultas,?

    el uso del Stopwatch esta correcto, ya que en la doc del mismo apunta justo a esto

    saludos


    Leandro Tuttini

    Blog
    Buenos Aires
    Argentina
    jueves, 10 de febrero de 2011 4:18
  • Se demora lo mismo, 10 segundos. Hasta ahora el foreach es lo mas rapido (2 segundos) pero aun es lento.

    Pasa que mi objeto A (A es el objeto que esta dentro de la lista) esta compuesta por tres propiedades que a son de tipo otras clases, y cuando seteo estas propiedades en null, el foreach tarda 0 segundos.

    Me he dado cuenta que al llamar al metodo ToList() del IEnumerable, este se tarda 2 segundos tambien, lo que me deja perplejo ya que en otra parte del programa tengo otra lista ienumerable<otraclase> y el ToList() es automatico, y peor aun esta otra lista tiene mas registros y es mas compleja desde el punto de vista de que tiene mas propiedades.

    Aporte un poco mas al tema por si ayuda en algo, documentar mas mi problema.

    Gracias y Saludos.

    jueves, 10 de febrero de 2011 7:24
  • Ya resolvi el problema, pasa que realizar funciones como Count(), Sum() o ToList() sobre una lista IEnumerable es bastante lento, (aqui encontre una explicacion: http://rapidapplicationdevelopment.blogspot.com/search?q=ToList). Mi proyecto funciona de la siguiente manera, realizo un procedimiento almacenado, relleno un datatable y obtengo una lista IEnumerable mediante el metodo asEnumerable del datatable, por lo tanto en mis metodos yo retornaba la lista IEnumerable.

    Para la solucion finalmente, segui el consejo de esta pagina (http://stackoverflow.com/questions/334579/do-you-tolist) en donde en vez de retornar la lista IEnumerable, inmediatamente al conseguir el IEnumerable, obtengo una Lista a traves del metodo ToList() y finalmente retorno esta lista.

    Lo que me deja la duda porque al hacer el ToList() inmediatamente tarda 0 segundos y cuando lo realizo despues tarda mucho mas.

    Gracias y Saludos.

     

    viernes, 11 de febrero de 2011 19:14
  • Lo que me deja la duda porque al hacer el ToList() inmediatamente tarda 0 segundos..

    Hola GRACIAS POR compartir la solución. Mira seguramente es que al poner ToList() la convertis a un tipo de dato que tiene muchas menos cosas (propiedades metodos) que si no especificas, además seguramente al especificar ToList() ya el framework sabe un "poco más" que tipo de datos vas a usar

    jueves, 17 de marzo de 2011 15:25