user356178
user356178

Reputation:

C# Performance of LINQ vs. foreach iterator block

1) Do these generate the same byte code?

2) If not, is there any gain in using one over the other in certain circumstances?

// LINQ select statement
return from item in collection
    select item.Property;

// foreach in an iterator block
foreach (item in collection)
    yield return item.Property;

Upvotes: 10

Views: 10119

Answers (2)

mmix
mmix

Reputation: 6308

  1. They don't generate the same code but boil down to the same thing, you get an object implementing IEnumerable<typeof(Property)>. The difference is that linq provides iterator from its library (in this case most likely by using WhereSelectArrayIterator or WhereSelectListIterator) whereas in the second example you yourself generate an iterator block that dissects a collection. An iterator block method is always, by ways of compiler magic, compiled as a separate class implementing IEnumerable<typeof(yield)> which you don't see but instantiate implicitly when you call iterator block method.

  2. Performance wise, #1 should be slightly (but just slightly) faster for indexable collections because when you loop through the resulting IEnumerable you go directly from your foreach into collection retrieval in an optimized linq iterator. In example #2 you go from foreach into your iterator block's foreach and from there into collection retrieval and your performance depends mostly on how smart the compiler is at optimizing yield logic. In any case I would imagine that for any complex collection mechanism the cost of retrieval marginalizes this difference.

IMHO, I would always go with #1, if nothing else it saves me from having to write a separate method just for iterating.

Upvotes: 8

Cameron MacFarland
Cameron MacFarland

Reputation: 71956

  1. No they don't generate the same byte code. The first one returns a pre-existing class in the framework. The second one returns a compiler generated state machine that returns the items from the collection. That state machine is very similar to the class that exists in the framework already.

  2. I doubt there's much performance difference between the two. Both are doing very similar things in the end.

Upvotes: 2

Related Questions