It doesn't seem to do squat for the following test program. Is this because I'm testing with a small list?
static void Main(string[] args)
{
List<int> list = 0.UpTo(4);
Test(list.AsParallel());
Test(list);
}
private static void Test(IEnumerable<int> input)
{
var timer = new Stopwatch();
timer.Start();
var size = input.Count();
if (input.Where(IsOdd).Count() != size / 2)
throw new Exception("Failed to count the odds");
timer.Stop();
Console.WriteLine("Tested " + size + " numbers in " + timer.Elapsed.TotalSeconds + " seconds");
}
private static bool IsOdd(int n)
{
Thread.Sleep(1000);
return n%2 == 1;
}
Both versions take 4 seconds to run.
Task Parallel Library cares about the static type of the sequence. It should be IParallelEnumerable<T>
for the operations to be handled by the TPL. You are casting the collection back to IEnumerable<T>
when you call Test
. Therefore, the compiler will resolve .Where
call on the sequence to System.Linq.Enumerable.Where
extension method instead of the parallel version provided by the TPL.
(Updating for .NET4 since this question ranks pretty high in a Google search for AsParallel())
Just a few changes will allow your example to work as I imagine you expected.
Change List<int> list = 0.UpTo(4);
to var list = Enumerable.Range(0, 4);
Your example would work if you added a function overload with a signature that takes a ParallelQuery...
private static void Test(ParallelQuery<int> input)
{
var timer = new Stopwatch();
timer.Start();
int size = input.Count();
if (input.Where(IsOdd).Count() != size / 2)
{
throw new Exception("Failed to count the odds");
}
timer.Stop();
Console.WriteLine("Tested " + size + " numbers in " + timer.Elapsed.TotalSeconds + " seconds");
}
Alternatively, you could use LINQ syntax....
private static void Test(ParallelQuery<int> list)
{
var timer = Stopwatch.StartNew();
if ((from n in list.AsParallel()
where IsOdd(n)
select n).Count() != (list.Count() / 2))
{
throw new Exception("Failed to count the odds");
}
Console.WriteLine("Tested " + list.Count() + " numbers in " + timer.Elapsed.TotalSeconds + " seconds");
}
Hope this helps someone!
As Parallel works by putting your stuff into the ThreadPool. Also, how many cores do you have? If you're working on a single core machine that will still take about 4s to run.