tim
tim

Reputation: 1369

LINQ is select new necessary for efficiency

If I am selecting a subset of elements out of a list am I gaining anything by doing a select new to just get only the properties I will be using. Or does the compiler just optimize that out so I can stop encumbering myself with the select new, e.g.:

var q = from n in TheseGuysHaveABunchOfProperties
        where n.State == "AK" 
        select new { Name = n.Name, Phone = n.Phone };

q.ToList().ForEach(x => Debug.WriteLine(x.Name + x.Phone);

vs.

var q = from n in TheseGuysHaveABunchOfProperties
        where n.State == "AK" select n;

q.ToList().ForEach(x => Debug.WriteLine(x.Name + x.Phone);

Upvotes: 1

Views: 546

Answers (5)

user180326
user180326

Reputation:

Not if you're doing LINQ to Objects. It is more likely to be slower as you copy and allocate more temporary variables. In case of LINQ to SQL, it is the other way around as you reduce the amount of data that is copied from the database.

Edit: This describes the common case. In case of LINQ to Objects, it could be faster copy objects if they are expensive to retrieve, and used more than once in your select statement. In case of LINQ to SQL, take case to not select properties you don't actually use.

Upvotes: 7

Brian Genisio
Brian Genisio

Reputation: 48137

First off, @jdv is correct. +1 to him. I'd like to add that f you are worried about performance, drop the ToList(). This is creating a copy of your data just to enumerate over it. You are now enumerating over it twice.

Instead, use a foreach loop normally:

foreach(var x in q)
    Debug.WriteLine(x.Name + x.Phone)

If you really like the functional approach of a ForEach method, create the extension on IEnumerable<T>:

public static void ForEach<T>(this IEnumerable<T> set, Action<T> action)
{
    foreach(T item in set)
        action(item);
}

This will be significantly faster than ToList().ForEach()

Upvotes: 2

Keltex
Keltex

Reputation: 26426

You absolutely do want to use select new. If TheseGuysHaveABunchOfProperties has a lot of properties (and hence data) when you do .ToList() you enumerate the collection completely. So you have a list in memory with every single object with every single property.

By doing select new before ToList, your objects in the list will only have the two properties you need.

If you can avoid doing ToList before ForEach, you won't have this problem. Of course the memory use, etc depends on the size of the list and the number of properties in TheseGuysHaveABunchOfProperties.

Upvotes: 0

abatishchev
abatishchev

Reputation: 100278

select new creates a anonymous type. In case when you don't need it, you probably should not use it.

Rather more efficiency will grant you correct string comparison:

where String.Equals(m.State, "AK", StringComparison.Ordinal); // or OrdinalIgnoreCase

Upvotes: 0

Randy Minder
Randy Minder

Reputation: 48422

You generally only use Select New when you want to generate a new type (an anonymous type). It's not really a matter of efficiency but more a matter of what types you need to deal with.

Upvotes: 1

Related Questions