Linq count vs IList count

29 浏览
0 Comments

Linq count vs IList count

如果我有以下的IEnumerable列表,它来自某个存储库。\n

IEnumerable items = _someRepo.GetAll();

\n哪个更快:\n

items.Count(); // 在IEnumerable接口上使用Linq。

\n还是\n

List temp = items.ToList(); // 转换为List
temp.Count(); // 在列表上进行计数

\n使用Linq的Count()比将IEnumerable转换为List然后执行Count()更快吗?\n更新:稍微改进了问题,使其更加实际。

0
0 Comments

Linq count vs IList count问题的出现原因是两种方法在计算集合元素数量时的性能和内存分配上的差异。解决方法是根据具体的背景类型选择合适的方法。

在一般情况下,无论是使用Linq的Count()方法还是使用IList的Count属性,都需要完全遍历集合。但在某些情况下,背景类型可能提供了直接确定数量的机制,从而可以实现O(1)的性能。具体可以参考'S'的答案。

调用ToList()方法的版本会有额外的CPU开销,尽管非常小且可能难以测量。它还会分配额外的内存,而不会被其他方法分配。如果集合数量很大,这将是更大的问题。

但是这并不是绝对的。底层集合可能有一个Count属性,Linq会使用它。

这是一个重要的细微之处。ToList()方法的时间复杂度总是O(n),而Count()方法的时间复杂度可能是O(1)。因此,真正的答案是“这取决于背景类型”。

很多集合同时实现了IEnumerable和ICollection接口,这种情况下可以使用Count属性。

0
0 Comments

Linq count vs IList count:原因和解决方法

在上述内容中,对比了使用Linq的Count方法和使用IList的Count属性来获取集合的元素个数。测试结果显示,使用Linq的Count方法更快、更节省内存,并且在再次遍历已经枚举过的集合时速度更快。

在测试中,调用IEnumerable.Count()的平均时间为约4个时钟周期,而创建一个新的列表并获取其Count属性的平均时间约为10,000个时钟周期。

如下所示,可以看到测试的代码:

void Main()
{
    IEnumerable ienumerable = GetStrings();
    var test1 = new Stopwatch();
    test1.Start();
    var count1 = ienumerable.Count();
    test1.Stop();
    test1.ElapsedTicks.Dump();
    var test2 = new Stopwatch();
    test2.Start();
    var count2 = ienumerable.ToList().Count;
    test2.Stop();
    test2.ElapsedTicks.Dump();
    var test3 = new Stopwatch();
    test3.Start();
    var count3 = ienumerable.Count();
    test3.Stop();
    test3.ElapsedTicks.Dump();
}
public IEnumerable GetStrings()
{
    var testString = "test";
    var strings = new List();
    for (int i = 0; i < 500000; i++)
    {
        strings.Add(testString);
    }
    return strings;
}

在第二种情况下,需要花费时间来创建一个新的集合,并从现有集合中提取Count属性。因此,Linq的优化方法更快地返回了Count值。

在第三次测试中,平均时钟周期下降到约2个,因为它立即返回了之前已经计算过的Count值。

然而,真正的成本在于内存消耗,这是你应该更关注的问题。

最后,需要注意的是,在枚举集合时不要在枚举中使用Count()方法。这样做会重新枚举集合,可能导致冲突。如果在迭代集合时需要使用Count,正确的方法是使用.ToList()创建一个新的列表,并在迭代该列表时引用Count属性。

总结起来,Linq的Count方法比IList的Count属性更快、更节省内存,在再次遍历已经枚举过的集合时速度更快。然而,内存消耗是需要更关注的问题。对于在枚举集合时使用Count()方法的情况,应该使用.ToList()方法来创建一个新的列表,并在迭代该列表时引用Count属性。

0
0 Comments

Linq中的Count方法和IList中的Count方法存在一些不同之处。Linq中的Count方法在性能上进行了一些改进,使其能够在不需要枚举整个集合的情况下返回结果。而IList中的Count方法则直接返回集合中的元素数量。

为了能够实现这种性能上的改进,Linq中的Count方法首先会检查集合是否是ICollection类型的,如果是,则直接返回ICollection的Count属性。如果集合不是ICollection类型的,再检查集合是否是ICollection类型的,如果是,则直接返回ICollection的Count属性。如果集合既不是ICollection类型的,也不是ICollection类型的,Linq中的Count方法会通过枚举集合的方式来计算元素数量,并返回结果。

而IList中的Count方法在实现上没有这种性能优化。它只是直接返回集合中的元素数量。

解决这个问题的方法是直接调用Linq中的Count方法。因为Linq中的Count方法在性能上进行了优化,能够更快地返回结果。如果集合实现了ICollection接口但没有实现其泛型版本,直接调用Count方法会更快。此外,不先调用ToList方法可以避免额外的List实例的分配,这虽然不是非常昂贵的操作,但在可能的情况下避免不必要的内存分配是更好的选择。

总结起来,Linq中的Count方法在性能上进行了优化,能够更快地返回结果。而IList中的Count方法则直接返回集合中的元素数量。为了获得更好的性能,建议直接调用Linq中的Count方法,特别是对于实现了ICollection接口但没有实现其泛型版本的集合。同时,不先调用ToList方法可以避免额外的List实例的分配,进一步提高性能。

0