More LINQ and Deferred Execution

In my previous post I talked about LINQ and Deferred Execution … I decided to continue expanding on this topic by showing how with LINQ to Objects it’s not only the query that is not executed immediately. Lets start from the basics… When you have a query such as this one

linq1.jpg

you can also write the above query in this way…
linq2.jpg

Yet you still did not execute that query… i.e the query2 that we have in the above code still has no values in it, it only holds an object that can give the values that you would want to have (It’s just a plan of execution). This might sound strange yet true… WHY? It’s because of Iterators. This is very important!!! For a better understanding of how iterators work have a look at this post.
So basically the iterator (which is an object returned by the Where method) will give you one value from a list at a time ONLY when you request it. Once you request the value, then you can go ahead and process that value and request the next value from that list. We use this a lot for example when we create a foreach statement.

When you have a LINQ query the same thing would happen as if we are in a foreach statement. When you project a value from your query you did not process the whole list you only got one value at a time!!! For a better understanding of how this works I created a small demo app where I developed my own Where Iterator that prints in a console. Here is the code for this demo app.

linq31.jpg

Basically I am creating an extension method for IEnumerable<int> and called it MyOwnWhere that in essence does the same job of the Where extension method of .Net 3.5 with the difference that this one prints to console. The interesting part of all this, is the output in the console…

linq4.jpg

As you can see when you have a where query you will be going through the list only once. The MyOwnWhere method (by using the yield keyword which is the keyword for creating iterators) is emitting an integer at a time. Lets us try to write down the flow of execution…

– The foreach statement requests a value from the query
– The query will start by asking the MyOwnWhere for a value
– MyOwnWhere will start filtering the source list
– Once an item matching the lambda function passed is found we yield that value
– The body of the foreach can process that value
– Once the value is processed the foreach will request the next value and this will go back to step 1 until the MyOwnWhere will stop yield values.

So basically everything is happening “Just in time” when you request it. To summarize all this we can even say

– You request a value
– The Iterator yields that value
– You process the value and request another one

The only instances where this does not apply is when you have things like OrderBy, Group or Joins…. When you use such methods you will need to get all values before executing the order by for example. So the Where would have to be processed fully before the order by can continue…. So if we change our code to this

linq5.jpg

than the result would be this

linq6.jpg

So here we had to process the whole list before we can order the result… No more just in time over here🙂

I hope that this post helps a bit more you guys to understand how LINQ to Objects actually works below the covers🙂

Happy new year to everyone🙂

Regards

One thought on “More LINQ and Deferred Execution

  1. Pingback: Visual Studio 2008 and Language Integrated Query (LINQ) | PocketPc Reviews

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