The more I use Parallel.ForEach and PLINQ in my code, the more faces and code review push backs I am getting. So I wonder is there any reason for me NOT to use PLINQ, at extreme, on each LINQ statement? Can the runtime not be smart enough to start spawning so many threads (or consuming so many threads from the thread pool) that the app performance would actually degrade instead of improve? The same question applies to Parallel library.
I do understand implications related to thread-safety and overhead of using multi-threading. I also realize not everything is good for parallelizing. All I am wondering about if I should stop defending my approaches and just give up on these two fine things because my peers think I'd better do thread control myself instead of relying on .NET facilities?
UPDATE: please assume the hardware is sufficiently good to satisfy prerequisites for use of multithreading.
I have researched this, and I agree that DbContext is not thread-safe. The pattern I propose does use multiple threads, but a single DbContext is only every accessed by a single thread in a single-threaded fashion.
No, it doesn't block and returns control immediately. The items to run in parallel are done on background threads.
Since the work in your parallel function is very small, the overhead of the management the parallelism has to do becomes significant, thus slowing down the overall work.
The execution of Parallel. Foreach is faster than normal ForEach.
It all comes down to two things:
Is the extra work required to partition the collection and synchronize the threads greater than the performance gain compared to a regular foreach
?
Are all the threads going to use a shared resource that will become a bottle neck?
An example of the second case is doing a Parallel.ForEach
over the results of a Linq to Sql
statement. In that case, if your results are coming from the DB very slowly, each thread may spend more time waiting for data to process than actually doing something.
See: http://msdn.microsoft.com/en-us/library/dd997392.aspx
To set the number of worker threads you can use .WithDegreeOfParallelism(N)
eg
var query = from item in source.AsParallel().WithDegreeOfParallelism(2)
where Compute(item) > 42
select item;
See http://msdn.microsoft.com/en-us/library/dd997425.aspx
When dig into performance questions this deep, I think the best thing to do is... measure, measure and measure. Even if somebody answered that PLINK is great and will boost the performance of your application, would you trust that without verifing it with profiling? Although general answers may exists you cannot spare the effort to measure the performance in your exact case. The overall performance depends on so many things and it can be that PLINK helps in one case but not in the other.
My personal experiences with PLINK is that after swicthing every LINQ query into PLINK the response times are way better when the load is small, and there is no difference when the load is around its maximum. But I can imagine a case where PLINK hurts the overall performance under a huge load. Have to check it for your own particular case.
Well... and if you want to convince other people that you are walking the right path, what else would be better than measurement results?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With