6

What would be the proper way of optimizing the following kind of statements:

IEnumerable<T> sequence = BuildSequence();
// 'BuildSequence' makes some tough actions and uses 'yield return'
// to form the resulting sequence.

Now, if I'm willing to take only some of the first elements, I could use something like:

sequence.Take(5);

And so, if my sequence from BuildSequence actually contains several thousands of elements, I obviously don't want all of them to be constructed, because I would only need 5 of them.

Does LINQ optimize this kind of operations or I would have to invent something myself?

2 Answers 2

14

The iterator block (yield return) handles this for you; an iterator block is a streaming API; work only happens during each MoveNext() call on the iterator (or on Dispose()). Because Take() also doesn't read the entire stream, this behaviour is preserved.

Note, however, that some operations need to buffer the data locally - GroupBy and OrderBy most notably; but as long as you use non-buffering operations, you are fine.

For example:

static IEnumerable<int> ReadInts() {
    var rand = new Random();
    while(true) yield return rand.Next();
}
...
int count = ReadInts().Take(10).Count(); // 10 - it doesn't loop forever
Sign up to request clarification or add additional context in comments.

2 Comments

That while loop looks quite frightening at first site, and in all honesty I could see some developers freaking out if they saw that in source code and didn't have an understanding of how enumeration/yield works.
@m-y almost reason enough to add it to the code - to give them a reason to freak out and learn
0

You should take a look on this:

LINQ and Deferred Execution

1 Comment

strictly speaking, this relates more to buffered/non-buffered that it does to deferred. A deferred but buffered operation would still have to consume the entire set of data... simply "not quite now".

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.