Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ vs nested loop

Tags:

c#

.net

linq

The code Im maintaining has a common pattern like the following, a nested loop with an if to find certain elements.

        foreach (Storage storage in mStorage.Values)
            foreach (OrderStorage oStorage in storage.OrderStorage)
                if (oStorage.OrderStorageId == orderStorageId)

I was thinking to change this into LINQ:

        foreach (OrderStorage oStorage in (from storage in mStorage.Values
                                           from oStorage in storage.OrderStorage
                                           where oStorage.OrderStorageId == orderStorageId
                                           select oStorage))

But it doesnt seem all that appealing because it's less transparent whats going on here, more objects may be created costing performance in terms of both memory and cpu. Will there actually be more objects created or does the C# compiler emit code resembling the nested loop with an if inside?

like image 886
Serve Laurijssen Avatar asked Dec 09 '22 13:12

Serve Laurijssen


1 Answers

Will there actually be more objects created or does the C# compiler emit code resembling the nested loop with an if inside?

More objects; each LINQ operation (SelectMany, Where, Select etc) will result in a new place-holder object that represents the pending IEnumerable<T> query of that operation, and then when it is finally iterated, each of those will result in an enumerator instance, along with the context etc. Plus there is a captured-variable context for the hoisted orderStorageId, etc.

Note that the regular foreach will also result in an enumerator instance, but foreach has the advantage that it can also use duck-typed enumerators - which means that for things like List<T> it is actually using a struct enumerator, not a class enumerator. And of course using the local variable (orderStorageId) directly (rather than in an anonymous method) means that it doesn't need to be hoisted into a state/context object.

So yes, the raw foreach is more direct and efficient. The interesting question is: is the difference important. Sometimes it is, sometimes it isn't.

like image 159
Marc Gravell Avatar answered Dec 11 '22 06:12

Marc Gravell