0

Say I have a simple Linq query:

var x = words.Where(w => w.Length > 4).Select(w => w.ToUpper()).ToArray();

Will the compiler generate code that iterates over words once, filtering and transforming as it goes, or code that generates an intermediate enumeration and then iterates over that?

What if there's an OrderBy():

var x = words.Where(w => w.Length > 4).OrderBy(w => w).Select(w => w.ToUpper()).ToArray();

I could see the compiler either iterating once over words, filtering and uppercasing words as it goes and merging them into an already sorted IOrderedEnumerable, or I could see it generating an intermediate array, sorting that, and then transforming it.

George
  • 2,110
  • 5
  • 26
  • 57
  • 2
    [Dixin's Blog](https://weblogs.asp.net/dixin/linq-to-objects-deferred-execution-lazy-evaluation-and-eager-evaluation) has a good explanation about lazy and eager-evaluation. I'm sure you'll get all the information you need. – Sebastian Schumann Aug 02 '19 at 04:46
  • 1
    The LINQ Pocket Reference book, by Albahari, gives a good description of the data movement in queries. – Alexander Petrov Aug 02 '19 at 05:06
  • _"I could see the compiler either iterating once over words, filtering and uppercasing words as it goes and merging them into an already sorted IOrderedEnumerable"_ -- not sure how that would work, since changing the case of the data could also change the sort order. In any case, no...LINQ doesn't rearrange your query. It happens in exactly the sequence you specify, and will only enumerate the original source once per query, always. See marked duplicates. – Peter Duniho Aug 02 '19 at 05:08

1 Answers1

1

Rewrite the query as follows to see the flow of the data.

var x = words
    .Where(w =>
    {
        Console.WriteLine("Where: " + w);
        return w.Length > 4;
    })
    .Select(w =>
    {
        Console.WriteLine("Select: " + w);
        return w.ToUpper();
    })
    .ToArray();
Alexander Petrov
  • 13,457
  • 2
  • 20
  • 49