Should I be using LINQ for this query?

I read a fair bit about the efficiency of using LINQ, not using per loop, and from what I understand using a LINQ query will be a little slower, but generally worth it for convenience and expressiveness. However, I'm a little confused about how much slower it is if you have to use the query results in a for loop.

Let's say I have a set called Locations and a set of objects called Items. Each "item" can only belong to one "location". I want to link elements that are in the same place to each other. If I did it using a normal For Each loop, it would be something like this:

For Each it as Item in Items
   If it.Location.equals(Me.Location)
      Me.LinkedItems.Add(it)
   End If
Next

      

However, if I were to use LINQ, it would be as follows:

For Each it as Item in Items.Where(Function(i) i.Location.equals(Me.Location))
   Me.LinkedItems.Add(it)
Next

      

Now my question is that the second option (LINQ) will loop through the entire set of 'Items' to complete the query and then view the results to add them to the list, resulting in essentially two loops, or will there be does he do one loop like the first (for each) option? If the answer is the first, I guess it would be silly to use LINQ in this situation.

+2


source to share


2 answers


It will do one loop - it is lazy evaluated.

However, you can do better than this. What type LinkedItems

? If it has an appropriate method AddRange

, you should be able to:

Me.LinkedItems.AddRange(Items.Where(Function(i) i.Location.equals(Me.Location)))

      


More on lazy evaluation



It basically Where

supports an iterator and only finds the next matching element when you query for it. In C #, the implementation would look something like this:

// Error handling omitted
public static IEnumerable<T> Where(this IEnumerable<T> source,
                                   Func<T, bool> predicate)
{
    foreach (T element in source)
    {
        if (predicate(element))
        {
            yield return element;
        }
    }
}

      

This is the use yield return

here that would make it lazy appreciated. If you are not familiar with C # iterator blocks, you can check out these articles that explain them in more detail.

Of course, Where

could have been implemented "by hand" instead of using an iterator block, but the above implementation is sufficient to show lazy evaluation.

+8


source


It will execute the request once, as you are viewing the Items.Where list. In your case, that's the pre-filtered list of conditions you want, and you really should go with LINQ.



+3


source







All Articles