Iterando sobre una colección

Creo este artículo para denunciar una excesiva e innecesaria conversión a lista de los enumerados.  Un error muy común a la hora de trabajar con colecciones, en concreto,  a la hora de recorrer un enumerado.

Una forma de gasto innecesario de tiempo y energía.

Un enumerado tiene un puntero a cada objeto de este que será incrementado en un bucle foreach, completando el acceso a cada objeto en la colección.

 

IEnumerable<Product> theProducts = Provider.GetProducts();

foreach(var p in theProducts)
{
   DoSomethingWithProduct(p);
}

 

 

 

Sin embargo, antes de iterar sobre el enumerado, sólo dios sabe si basándose  en alguna extraña conjetura o en

diversas teorías conspiratorias, muchos programadores convierten el enumerado a una lista.

 

 

                List<Product> theProducts = Provider.GetProducts().ToList();
                foreach (var p in theProducts)
                {
                    DoSomethingWithProduct(p);
                }

 

 

Esta operación ToList, creará una copia en memoria de la colección, y tiene complejidad temporal de O(n).

 

Veamos una comparación  al iterar de una u otra forma

 

namespace CollectionPerformance
{
    class Program
    {
        static int num = 500;

        static void Main(string[] args)
        {

            IEnumerable theProducts = Provider.GetProducts();
            Console.WriteLine("Starting Iterations");
            Console.WriteLine("Iterating through IEnumerable");
            MeasureTime(IterateThroughIEnumerable);

            Console.WriteLine("Iterating through  List");

            MeasureTime(IterateThroughList);
            Console.WriteLine("Press to quit...");
            Console.ReadKey();


        }
        static void IterateThroughIEnumerable()
        {
            for (int i = 0; i < num; i++)
            {
                IEnumerable theProducts = Provider.GetProducts();
                foreach (var p in theProducts)
                {
                    DoSomethingWithProduct(p);
                }
            }



        }

        static void IterateThroughList()
        {
            for (int i = 0; i &lt; num; i++)
            {
                List theProducts = Provider.GetProducts().ToList();
                foreach (var p in theProducts)
                {
                    DoSomethingWithProduct(p);
                }
            }



        }

        static void DoSomethingWithProduct(Product product)
        {

        }

        static void MeasureTime(Action action)
        {
            Stopwatch stp = Stopwatch.StartNew();
            action();

            Console.WriteLine($"Took {stp.Elapsed.ToString()}");
        }

    }
}

 

Al iterar 500 veces sobre la colección de productos, da  un resultado de 3 segundos sin copiar a lista y 18 con la copia.

Deja un comentario

Si continuas utilizando este sitio aceptas el uso de cookies. más información

Los ajustes de cookies de esta web están configurados para "permitir cookies" y así ofrecerte la mejor experiencia de navegación posible. Si sigues utilizando esta web sin cambiar tus ajustes de cookies o haces clic en "Aceptar" estarás dando tu consentimiento a esto.

Cerrar