Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / LINQ

LINQ Deferred Execution - Lazy Evaluation

5.00/5 (2 votes)
29 Jul 2013CPOL1 min read 13K  
In this post, we’ll see how the type of execution can boost performance in LINQ.

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:-
C#
    //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.

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

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)