I have a set of items in workload that can run in parallel. Sometimes there is just 1, sometimes there are a lot. It is noticeably faster when I Parallel.ForEach over a large workload. So it seems to be a suitable use of Parelle.ForEach.
I've read that for workloads of 1 or 2, it's better to not Parallel.ForEach over them. Does this mean I have to wrap every Parallel.ForEach of a variable workload size with this sort of pattern?
if (workItems.Count==1)
{
foreach (MyItem item in workItems)
{
bool failed = WorkItWorkIt(item);
}
}
else
{
Parallel.ForEach(workItems, (item, loopState) =>
{
bool failed = WorkItWorkIt(item);
});
}
Well, Parallel.ForEach
with a single task will add a bit of overhead, but not tremendous. Parallel.ForEach
will actually reuse the main thread, which means there's really only some small checks, then it runs your work. Two work items will be potentially worthwhile, and more is only better.
The bigger issue with Parallel.ForEach
isn't actually the number of items in the collection, it's the amount and type of work being done per item. If you have very small bodies (in terms of CPU time, etc), the cost of parallelizing can outweigh the benefits quickly.
If your work per item is CPU bound and reasonably large, then it's fairly safe to always parallelize, without checks.
That being said, the best solution, as always, is to actually profile your application with all of your various options.