views:

125

answers:

1

What LINQ to Objects optimization techniques do you use or have you seen in the wild?

While waiting for "yield foreach" and other language/compiler optimizations to arrive in C# in 201x, I'm interesting in doing everything possible to make using LINQ everywhere less of a performance pain.

One pattern I've seen so far is creating custom IEnumerable implementations for specific combinators such that the enumerable is not being re-enumerated several times.

+5  A: 

One that I've spotted a few times - don't use:

if (query.Count() > 0)

... use this instead:

if (query.Any())

That way it only needs to find the first match.

EDIT: You may also be interested in a blog post I recently wrote about optimisations which could be in LINQ to Objects but aren't (or weren't in .NET 3.5).

Additionally, if you're going to do a lot of x.Contains(y) operations and x is the result of an existing query (i.e. it's not already going to be some optimised collection), you should probably consider building a HashSet<T> from x to avoid a linear scan (performing the query to produce x's results) on each iteration.

Jon Skeet
That's an excellent tip!
Timothy Khouri
Certainly Any is much better than Count. I just disassembled BCL 4 and ElementAt is now optimized for ILists; it does a simple list[index] lookup in that case.
Bent Rasmussen
I just checked out the BCL 4 Reverse() and it's also slow. It's very trivial to implement a random access reverse enumerable as you mention. I just did so and it's significantly faster. So I'll include this in my bag of tricks.
Bent Rasmussen
You might want to check out the optimizations and tricks I've applied in Extensia: extensia.codeplex.com; it makes use of LINQ to Objects everywhere and includes a hybrid sequence/list type for buffered access to enumerables.
Bent Rasmussen