Sunday, 23 June 2013

LINQ Deferred Execution - Lazy Evaluation


Queries are executed in many ways. The types can be broadly classified into Deferred/Lazy Execution and Immediate Execution.

In this post, we’ll see how the type of execution can boost performance in LINQ.

In the videos, we first showcase an example of Deferred/Lazy execution. This type of a statement is executed only when the output is a necessity to proceed further in the program; until then, the execution can wait! This is the standard way in which most Language Integrated Queries (LINQ) are executed.

Deferred Execution is extremely helpful in scenarios where you don’t need the entire output to be computed at a point of time. This is made possible through the use of interation over an IEnumerable having a yield functionality. A detailed example is present in the videos.

When there’s a need to do functions like Sort(), Distinct(), etc. then an Immediate execution is necessary to compute the entire output in one go. This can be facilitated by using the ToList() function.

We wind up by performing Immediate and Deferred execution partially on an input. For a deeper understanding on all that has been mentioned above, please check out the 5 video links where I go through the demo in full detail.


C# LINQ Deferred Execution (Part 1)




C# LINQ Deferred Execution (Part 2)




C# LINQ Deferred Execution (Part 3)



C# LINQ Deferred Execution (Part 4)




C# LINQ Deferred Execution (Part 5)




The code typed-in during the tutorial-session is as follows:-


        //Deferred & Immediate Execution
        //Deferred == Lazy Execution
        //Lazy => Not Executing until necessary! (LINQ)

        var Details = new List<int?> { 30, 40, 10, 15, 25 };

        var output = (from person in Details
                      where person.Value > 20
                      select person.Value);// ToList();

        foreach (var item in output)
            MessageBox.Show(item.ToString());

        foreach (var item in GetEvensImmediate(6))
            MessageBox.Show(item.ToString());

        foreach (var item in GetEvensDeferred(6))
            MessageBox.Show(item.ToString());

        foreach (var item in GetEvensPartiallyDeferred(6))
            MessageBox.Show(item.ToString());

        //var output = (from person in Details
        //              where person.Value > 20
        //              select person.Value).Take(2).ToList();

        //foreach (var item in output)
        //{ }

        //foreach (var item in output)
        //{ }

        //foreach (var item in output)
        //{ }


    //Immediate Execution function
    public List<int> GetEvensImmediate(int maxLimit)
    {
        var result = new List<int>();

        for (int i = 0; i < maxLimit; i++)
        {
            if (i % 2 == 0)
                result.Add(i);
        }

        return result;
    }

    //Deferred or Lazy Execution
    //IEnumerable<int> is an Iterator Interface type; List<int> isn't
    //When we use yield, we needn't worry about default return values.
    public IEnumerable<int> GetEvensDeferred(int maxLimit)
    {
        for (int i = 0; i < maxLimit; i++)
        {
            if(i == 10)
            //if (i % 2 == 0)
                yield return i;
        }
    }

    public IEnumerable<int> GetEvensPartiallyDeferred(int maxLimit)
    {
        var result = new List<int>();

        for (int i = 0; i < maxLimit; i++)
        {
            if (i % 2 == 0)
                result.Add(i);
        }

        foreach (var item in result)
            yield return item;
    }


Thank you for reading this post and watching the videos. Please Subscribe, Comment, and Rate the channel if you liked the videos.

C# Blog Link

Goto C# Experiments to access more of such content! Thanks again!