Reputation: 26281
Let's say I have these two methods:
public BigInteger PFactorial(int n)
{
return Enumerable.Range(1, n)
.AsParallel()
.Select(i => (BigInteger)i)
.Aggregate(BigInteger.One, BigInteger.Multiply);
}
public BigInteger Factorial(int n)
{
BigInteger result = BigInteger.One;
for(int i = 1; i <= n; i++)
result *= i;
return result;
}
The following were the results I got:
PFactorial(25000) -> 0,9897 seconds
Factorial(25000) -> 0,9252 seconds
I understand that PLINQ has some overhead because of the threads setup, but with such a big n
I was expecting PLINQ to be faster.
Here is another result:
PFactorial(50000) -> 4,91035 seconds
Factorial(50000) -> 4,40056 seconds
Upvotes: 10
Views: 806
Reputation: 19149
Parallel is not really possible with aggregate. At least i cant imagine that in my mind. Any way, You should make parallelization possible by dividing your list into chunks. Find those results. and finally multiply chunks. Here is the fast way of PLinq.
static public BigInteger PFactorial(int n)
{
var range = Enumerable.Range(1, n).Select(x => (BigInteger) x).AsParallel();
var lists = range.GroupBy(x => x/(n/Environment.ProcessorCount)).Select(x => x.AsEnumerable());
var results = lists.Select(x => x.Aggregate(BigInteger.One, BigInteger.Multiply));
var result = results.Aggregate(BigInteger.One, BigInteger.Multiply);
return result;
}
Test
PFactorial(50000) -> 1,41 seconds
Factorial(50000) -> 2,69 seconds
Edit: As mentioned by Servy and Chatzigiannakis if you dont use seed it can perfectly use parallelization and you get pretty much same results as above (a bit faster).
return Enumerable.Range(1,n).Select(x => (BigInteger)x).AsParallel().Aggregate(BigInteger.Multiply);
Upvotes: 10
Reputation: 7616
Please do not assume that pLinQ is always faster than LinQ. PLinQ execution time based on many condition
Use PLinQ only when there are more elements and have some CPU intensive query. I'll suggest to use System.Threading.Thread.Sleep(1)
in a function to emulate the CPU load as cycle delay and then call that function from LinQ and PlinQ for 10000 times. Then you can see the difference. Please find sample here
Your current function Factorial actually not doing any CPU intensive task and reason PLinQ taking more time, because it dived the query to run in multiple core and consolidate the result of individual core to single output, which take little more time then normal.
Also make sure you are using multi core processors (minimum 4 will give you good analysis)
Upvotes: 1