.NET Developments

Sep 26 2008   2:50PM GMT

The LINQ Equation

Brein Matturro Profile: Brein Matturro

Language Integrated Query (LINQ) is a new object querying paradigm that released with Microsoft’s .Net Framework version 3.5.  It allows a programmer to write SQL-style code to access objects within lists or collections or arrays.  It is quite powerful but what about performance?  I will attempt to show an un-biased comparison of a few object list querying techniques and together we’ll look at the results and perhaps even learn something.

The collections I’m working with are dogs, owners, and vets.  Each dog has an owner and a vet.  Each collection is implemented as a generic list (List<dog>, List<owner>, and List<vet>).  I have a single routine that loads up each collection and associates dogs with owners and vets.  One of the attributes of a dog is the brand of food the dog likes.  We’re going to look at a simple count “Query” against the collection of dogs where the food brand is “Purina”.

The legacy way of counting items in a collection is the basic foreach loop where we loop through the collection looking for a particular attribute value and then increment a counter based on the check such as:
foreach (DLDog Dog in Dogs)
  if (Dog.FoodBrand == "Purina")

In this case we could return the value of count thereby returning the answer.

In .NET 2.0 we discovered the concept of the generic delegate and the action and predicate delegate types.  This enables us to simplify our query for food brand as follows:
  MyActionCount = 0;
  return MyActionCount;
  private void MyAction(DLDog Dog)
  if (Dog.FoodBrand == "Purina")

In this example we create a function called MyAction that statisfies the Action action generic delegate and now we can provide many different implementations of our count process.  There is an assumption that we have defined MyActionCount elsewhere in the source.  We can actually simplify this even further by putting the delegate inline as follows:
  int Count = 0;
  delegate(DLDog Dog)
  if (Dog.FoodBrand == "Purina") { Count++; }
  return Count;

In this case, we don’t need the dependent variable MyActionCount and the function is self-sufficient.  Now some would argue that this is much less readable but I would say it is less well known.  Once the delegate syntax is understood and comfortable, this syntax is easily understood.

So what about LINQ?  Here is the same “query” expressed as a LINQ to objects query:
  var query = from dog in Dogs select dog;
  return query.Count(n => n.FoodBrand == "Purina");

This code is very readable but the syntax is extremely foreign.  Under the covers, this is represented very similarly to the inline delegate method of performing the query but it is done so using much easier to read syntax.  If we look at the IL Code generated for each of these looping structures we will notice very similar constructs being used at the lower level.  That is not to say that LINQ is just syntactical sugar – it is a compiler change that allows it but it builds on the generics and anonymous methods given to us in .NET 2.0.

 Comment on this Post

There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to:

Share this item with your network: