Psychic LINQ


A relatively short post on cargo cult programming, particularly related to LINQ.

LINQ is a fantastic technology. The idea of making a platform-agnostic query language is a fantastic idea. You can write the same query, in C#, over an in-memory list or a database and from the client point of view treat it in the same way. Isn’t it wonderful!

I’ve recently carried out a number of job interviews where candidates had to answer the following question:

If you wanted to find all Customers whose name was “Isaac”, why would you use a .Where() clause over a collection of T rather than using a foreach loop and manually construct the result set?

The results were varied. What I was looking for was a discussion of the benefits of declarative versus imperative code; what versus how etc.; composability of queries etc.

Strangely enough, the most common answer I got was "LINQ is faster than a foreach loop". Why? Either because LINQ somehow "optimises" code to make it faster, or because it "doesn’t need to loop through a collection – it just ‘does’ a where clause over the collection so that it instantly finds it". Almost as if C# is doing magic! In both cases the candidates could not justify their beliefs with evidence – it was just their feeling that that “must” be the case.

Now, lets talk about the reality. I would direct everyone to Jon Skeet’s fantastic EduLinq blog series to get an in-depth understanding of how LINQ over objects works, but always remember this simplification:

The only methods and properties that LINQ has for all its query methods are sourced from IEnumerator <T>

  • Boolean MoveNext();
  • T Current { get; }

    That’s it. Think about that. There is no magic involved. If you do a Where() clause over a collection, you will enumerate the entire source. There is no “pixie dust” that will give LINQ the answer quicker than a foreach loop and an if / then statement – and bear in mind, foreach loops are just syntactic sugar over IEnumerator, just like the using statement wraps IDisposable.

Advertisements

2 thoughts on “Psychic LINQ

  1. My first though regarding using LINQ vs using a foreach loop was that the LINQ query would be evaluated lazily and depending on usage (if you only ever iterate over the IEnumearble) would be less memory intensive.

    Good points about composability, declarative style and the what vs how arguments.

    1. Indeed, lazy evaluation in one of the enablers for the composability of LINQ – but you can achieve the same functionality yourself without LINQ by using the yield keyword. I’m planning on blogging about this shortly 🙂

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s