Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parallel ForEach using up very little processing power as time elapses

I have the following code running and as time passes by (an hour or two) i notice that it takes longer and longer to iterate through the items. Is there something that i'm doing which is causing this to occur? If so how can i fix it?

        int totalProcessed = 0;
        int totalRecords = MyList.Count();

        Parallel.ForEach(Partitioner.Create(0, totalRecords), (range, loopState) =>
        {
            for (int index = range.Item1; index < range.Item2; index++)
            {
                DoStuff(MyList.ElementAt(index));
                Interlocked.Increment(ref totalImported);
                if (totalImported % 1000 == 0)
                    Log(String.Format("Processed {0} of {1} records",totalProcessed, totalRecords));
            }
        });

         public void DoStuff(IEntity entity)
         {
              foreach (var client in Clients)
              {
                  // Add entity to a db using EF
                  client.Add(entity);
              }
          }

Thanks for any help

like image 952
zSynopsis Avatar asked Dec 09 '22 11:12

zSynopsis


1 Answers

ElementAt is very slow extension method with following implementation:

public static void T ElementAt(this IEnumerable<T> collection, int index) 
{
    int i = 0;
    foreach(T e in collection)
    {
        if(i == index)
        {
            return e;
        }
        i++;
    }
    throw new IndexOutOfRangeException();
}

It is obvious that it works longer when index is greater. You should use indexer MyList[index] instead of ElementAt.

like image 137
Victor Haydin Avatar answered Apr 20 '23 01:04

Victor Haydin