LINQ是选择新的效率所必需的

时间:2011-01-29 16:08:33

标签: c# linq

如果我从列表中选择一个元素的子集,我通过选择new来获得任何东西,只获得我将使用的属性。或者编译器是否只是优化了这一点,所以我可以停止使用select new来阻止自己,例如:

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);

5 个答案:

答案 0 :(得分:7)

如果你正在对象进行LINQ,那就不行了。复制和分配更多临时变量时,它更可能更慢。对于LINQ to SQL,当您减少从数据库复制的数据量时,它是另一种方式。

编辑:这描述了常见的情况。对于LINQ to Objects,如果它们的检索成本很高,并且在select语句中使用了多次,则它可能是更快的复制对象。对于LINQ to SQL,请注意不要选择实际不使用的属性。

答案 1 :(得分:2)

首先,@ jdv是正确的。 +1给他。我想补充一点,如果您担心性能,请放弃ToList()。这是为了枚举数据而创建数据的副本。你现在两次枚举它。

相反,通常使用foreach循环:

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

如果您真的喜欢ForEach方法的功能方法,请在IEnumerable<T>上创建扩展程序:

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

这将明显快于ToList().ForEach()

答案 2 :(得分:1)

当您想要生成新类型(匿名类型)时,通常只使用“选择新建”。这不是效率问题,而是需要处理的类型问题。

答案 3 :(得分:0)

select new创建一个匿名类型。如果您不需要它,您可能不应该使用它。

更高效率将为您提供正确的字符串比较:

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

答案 4 :(得分:0)

您绝对想要使用select new。当你执行.ToList()时TheseGuysHaveABunchOfProperties有很多属性(以及数据),你完全枚举了这个集合。所以你在内存中有一个列表,每个对象都有一个属性。

select new之前执行ToList,列表中的对象将只包含您需要的两个属性。

如果您可以避免在ToList之前执行ForEach,则不会出现此问题。当然,内存使用等取决于列表的大小和TheseGuysHaveABunchOfProperties中的属性数量。