views:

224

answers:

5

When you have some enumeration methods in some of your types (i.e. a custom collection), is it better to use LINQ syntax or just old school enumeration (for/foreach)?

Using .NET 3.5 is a given.

I am asking this for maximum performance and readability. The application is also designed to be parallel.

Which one would you favor?

+2  A: 

If you absolutely must wring every last drop of performance out, then a for/foreach loop is tough to beat for efficiency. However, if you're going for parallelism and readability, the Enumerable<T> extension methods and LINQ win hands down in my book.

John Feminella
Thanks, with plain LINQ would I get parallel execution? Or you mean PLINQ?
Joan Venge
You have to us PLINQ for that.
mfawzymkh
+6  A: 

Linq queries can be parallelised easily using PLinq (built into .net 4)

I personally find Linq easier to read, but it depends on you as a developer.

foreach (var item in collection)
{
    if (item.Value == SomeOtherValue)
        performSomeProcessing();
}

vs

foreach(var item in collection.Where(a => a.Value == SomeOtherValue))
{
    performSomeProcessing();
}

I think (although i've not personally benchmarked this) that the compiler optimises out the small function calls, so performance should not be noticably different.

Matthew Steeples
+2  A: 

I nearly always favor using LINQ over standard looping constructs in my collections, but the parallelization aspect changes things slightly.

If you're planning to use .NET 4.0, the parallel constructs (using Parallel.For in particular) will beat out PLINQ in terms of parallelization, provided you know the count in advance. The partitioners in PLINQ do a good job, but are made to be very general purpose, and cannot match the partitioning strategies available if the count is known in advance. This will tend to make Parallel.For outperform PLINQ when it's available to be used.

Reed Copsey
Thanks Reed. I didn't know Parallel.For was better when you know the count. What about Parallel.Foreach (don't know if there is one).
Joan Venge
You can make a Parallel.Foreach, but it doesn't have the advantages. The biggest thing with parallelizing effectively is partitioning, especially if you have many small work elements. Knowing the count allows parallel.for to do more intelligent partitioning up front, so it can group work items into blocks per task effectively, which reduces the synchronization overhead.
Reed Copsey
Thanks Reed. That makes sense.
Joan Venge
+1  A: 

LINQ to Objects performance is a mixed thing. Since it involves a lot of indirected calls (every lambda is one), it is slower, sometimes (when the lambda captures and uses variables from its outer scope) 3-4x times so. And, no, the compiler (neither C# nor JIT) won't optimize it away - it cannot inline virtual method calls, and that's what a call via a delegate effectively is. So if you strictly want performance, foreach is going to be slightly to significantly faster in any case.

PLINQ can alleviate the difference, but note that the penalty is significant enough that you might need 4 cores just to match up for it. On the other hand, it will scale up as number of cores increases, while a plain foreach will not.

Pavel Minaev
Thanks. What about Parallel.For?
Joan Venge
+2  A: 

It depends - does your iteration have side effects? If so, I would avoid using any form of LINQ, otherwise use LINQ and PLINQ for it's simple declaritive nature.

Eric Smith