Filip Ekberg's blog

March 25, 2010

Using Parallel Extensions in LINQ

Filed under: .NET, C#, Programming — Tags: , , , , — Filip Ekberg @ 4:16 pm

Once again, there was a little mistake in the last post I posted here which clearly didn’t effect the result that much. But it is still worth mentioning again. The ^ was not meant to be XOR, I was clearly thinking of Math.Pow.

In the last post I didn’t spend to much time talking about the Parallel Extensions for LINQ which are Really great and helpful; If you just love to replace traditional loops with LINQ-expressions you will probably find this post somewhat amusing.

So let’s dig down to the coding shall we!

First of all I have set up a smaller list with numbers, in this scenario we will just assume that we have a list of something and depending on the contents of that list, the time it takes to perform an action on that result, will differ. So here’s my list

1
var latency = new[] {1, 2, 4, 8};

Side note: new[]{} is really helpful, especially when you are creating examples like this!

And then I have a method that I want to run for each element in my list, which I will call PerformLogic

1
2
3
4
5
6
7
8
static int PerformLogic(int latency)
{
    var ms = 500 * latency;

    Thread.Sleep(ms);

    return ms;
}

In “traditional” programming, you would maybe do something like this:

1
2
3
4
for ( int i = 0; i < latency.Lenght; i++ )
{
    PerformAction(i);
}

But I don’t find that so amusing anymore, using LINQ is so much neater so instead of that for-loop we can actually do this:

1
(from i in latency select PerformAction(i)).ToList();

We don’t really have to write the expession like this though, since LINQ + .NET 4.0 is so smart, we can Refactor this to look somewhat like this:

1
(latency.Select(PerformLogic)).ToList();

The previous one is a bit more elaborate but this is fine aswell.

Making it parallel

We’ve reached the place where we no longer can refactor our code to make it faster, we can’t replace anything in the logic to make everything faster; We need to parallelize it!

Let’s have a look at what LINQ provides us with, oh, there’s an method called

1
.AsParallel

.

All I did now was changing the above code to this:

1
var result = (latency.Select(PerformLogic)).AsParallel().ToList();

And we have a parallelized query. For those with a fast mind can see that it will take about 7,5 seconds to run this since each of the “latency”-points will take itself times ½ second.

My final test-code looks like this

1
2
3
4
5
6
7
8
9
10
11
var latency = new[] {1, 2, 4, 8};

var start = DateTime.Now;

var result = (latency.Select(PerformLogic)).AsParallel().ToList();

var end = DateTime.Now;

Parallel.ForEach(result, Console.WriteLine);

Console.WriteLine("Execution time: {0}", (end - start));

And this is the output
LINQ Parallelism

No Comments »

No comments yet.

RSS feed for comments on this post. TrackBack URL

Leave a comment

Powered by WordPress