Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What does the Parallel.Foreach do behind the scenes?

So I just cant grasp the concept here. I have a Method that uses the Parallel class with the Foreach method. But the thing I dont understand is, does it create new threads so it can run the function faster?

Let's take this as an example. I do a normal foreach loop.

private static void DoSimpleWork()
        {
            foreach (var item in collection)
            {
                //DoWork();
            }
        }

What that will do is, it will take the first item in the list, assign the method DoWork(); to it and wait until it finishes. Simple, plain and works.

Now.. There are three cases I am curious about If I do this.

Parallel.ForEach(stringList, simpleString =>
            {
                DoMagic(simpleString);
            });

Will that split up the Foreach into let's say 4 chunks? So what I think is happening is that it takes the first 4 lines in the list, assigns each string to each "thread" (assuming parallel creates 4 virtual threads) does the work and then starts with the next 4 in that list? If that is wrong please correct me I really want to understand how this works.

And then we have this. Which essentially is the same but with a new parameter

Parallel.ForEach(stringList, new ParallelOptions() { MaxDegreeOfParallelism = 32 }, simpleString =>
            {
                DoMagic(simpleString);
            });

What I am curious about is this

new ParallelOptions() { MaxDegreeOfParallelism = 32 }

Does that mean it will take the first 32 strings from that list (if there even is that many in the list) and then do the same thing as I was talking about above?

And for the last one.

Task.Factory.StartNew(() =>
            {
                Parallel.ForEach(stringList, simpleString =>
                {
                    DoMagic(simpleString);
                });
            });

Would that create a new task, assigning each "chunk" to it's own task?

like image 677
Aleks Slade Avatar asked Dec 25 '17 13:12

Aleks Slade


People also ask

What does parallel ForEach do?

The Parallel. ForEach method splits the work to be done into multiple tasks, one for each item in the collection. Parallel. ForEach is like the foreach loop in C#, except the foreach loop runs on a single thread and processing take place sequentially, while the Parallel.

Does parallel ForEach improve performance?

In many cases, Parallel. For and Parallel. ForEach can provide significant performance improvements over ordinary sequential loops. However, the work of parallelizing the loop introduces complexity that can lead to problems that, in sequential code, are not as common or are not encountered at all.

Should you use parallel ForEach?

The short answer is no, you should not just use Parallel. ForEach or related constructs on each loop that you can. Parallel has some overhead, which is not justified in loops with few, fast iterations.

Does parallel ForEach wait?

You don't have to do anything special, Parallel. Foreach() will wait until all its branched tasks are complete. From the calling thread you can treat it as a single synchronous statement and for instance wrap it inside a try/catch.


1 Answers

Do not mix async code with parallel. Task is for async operations - querying a DB, reading file, awaiting some comparatively-computation-cheap operation such that your UI won't be blocked and unresponsive.

Parallel is different. That's designed for 1) multi-core systems and 2) computational-intensive operations. I won't go in details how it works, that kind of info could be found in an MS documentation. Long story short, Parallel.For most probably will make it's own decision on what exactly when and how to run. It might disobey you parameters, i.e. MaxDegreeOfParallelism or somewhat else. The whole idea is to provide the best possible parallezation, thus complete your operation as fast as possible.

like image 79
Zazeil Avatar answered Oct 26 '22 00:10

Zazeil