2

Below is code which I am using in Parrllel.Foreach. But it is taking same time as normal foreach. Here filingDataItems, nonPeriodic, periodiccells are data tables. Does this happening due to data tables?

System.Threading.Tasks.Parallel.ForEach(tempfilingReferences, T2 => { Filing f = new Filing( T2.Id, T2.DocumentPeriod, T2.FilingDate, T2.VersionId, T2.DocumentId, T2.PrimaryPeriodTypeId, T2.IssuedAsPreliminaryFlag, T2.IssuedAsAmendmentFlag, T2.FilingDetails, T2.CompanyId, GetFilingDataItems(filingDataItems, T2.Id, nonPeriodic, periodiccells, filingToPeriodList, DPTPList, posList), GetPeriods(filingToPeriodList, periodInfoList, T2.Id), GetFilingToPeriods(filingToPeriodList, T2.Id), true, false, AuditedDataType.Financials, T2.FilingTypeList ); lock (filingListnew) { filingListnew.Add(f); } }); 
5
  • 5
    You have all the overhead of setting up a parallel loop, but because you are locking to do the actual work, you have few of the benefits. Result = performance decrease. Commented Feb 16, 2015 at 11:17
  • @MatthewWatson said it all. Commented Feb 16, 2015 at 11:19
  • Things have to actually be parallizable to benefit here, you dont get a magic speed increase just by doing Parallel.ForEach Commented Feb 16, 2015 at 11:19
  • "Does this happening due to data tables?" - we don't know, you didn't show that code. Apart from the lock(), the methods GetFilingDataItems(), GetPeriods() and GetFilingToPeriods() may very well be slower when called in parallel. Commented Feb 16, 2015 at 11:25
  • Also note, that for small data sources or simple operations inside the loop the overhead of running stuff in parallel can overshadow the performance benefit Commented Feb 16, 2015 at 11:35

2 Answers 2

2

You are locking in the parallel part. So you wait in each thread for the active thread to remove the lock. So this is nearly the same as the sequencial foreach.

For example:

Parallel.Foreach:

Cycle1

Thread1: filingListnew.Add(Object1);

Thread2: locked

Thread3: locked

Thread4: locked

Cycle2

Thread1: locked

Thread2: filingListnew.Add(Object2);

Thread3: locked

Thread4: locked

Cycle3 ...

"Normal" foreach:

Cycle1

Main Thread: filingListnew.Add(Object1);

Cycle2

Main Thread: filingListnew.Add(Object2);

Cycle3 ...

As you can see in the examples you cannot gain performance the way you are using ParallelForeach.

Sign up to request clarification or add additional context in comments.

2 Comments

See Dmitry's answer, but to address that specific question: use concurrent collections (works best if you don't need it to be in any specific order).
If you just did the ParallelForeach for not blocking the main thread a long time you can move the whole foreach into an other thread
2

You'd rather not lock at each step, but try using LINQ:

 filingListnew.AddRange(tempfilingReference .AsParallel() .Select(T2 => new Filing(...))); 

If you have to preserve the order :

 filingListnew.AddRange(tempfilingReference .AsParallel() .AsOrdered() .Select(T2 => new Filing(...))); 

You may find useful to create the list, not adding to it:

 filingListnew = tempfilingReference .AsParallel() .AsOrdered() .Select(T2 => new Filing(...))) .ToList(); 

Linq is easy to switch between sequential/parallel just comment out AsParallel() (or put AsSequential())

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.