计数和容量有多快?

时间:2012-04-13 14:36:40

标签: c#

我经常写这样的代码:

if ( list.Count > 0 ) { }

效率这么高吗?此操作是否如下所示:

  • 遍历列表并计算其元素
  • 结果:986,000个元素
  • 986,000是否大于0?
  • return true

或者像这样:

  • 检索列表中存储的元素数量(986,000)
  • 986,000是否大于0?
  • return true

也就是说,为了获得列表中的元素数量,您是否必须在列表中一直计算,或者是在某处记录的元素数量?这是所有ICollection类的情况吗?

列表的Capacity怎么样?

5 个答案:

答案 0 :(得分:33)

  

我经常写这样的代码:if ( list.Count > 0 ) { }这有效吗?

是。它检索列表中的计数,该计数存储在列表中的字段中,并将其与零进行比较。

现在提出一个你没问过的问题:

  

if ( sequence.Count() > 0 ) { }怎么样? (注意Count()上的括号。)

我们在运行时询问序列,看看它是否是一个具有Count属性的列表,可以有效地计算。如果是,我们称之为。如果没有,我们一次计算整个序列一个项目,然后将其与零进行比较。

  

这不是非常低效吗?

  

什么会更有效?

if (sequence.Any())

  

为什么效率更高?

因为它试图迭代一个元素。如果成功,则Any为真;如果失败则Any为假。你不需要计算罐子里的软糖数量,以便知道是否有超过零。您只需要查看是否至少有一个。

除了效率更高之外,代码现在看起来像代码的预期含义。如果您打算询问“列表中是否有任何项目?”然后问“列表中有没有项目?”而不是“列表中的项目数是否大于零?”

  

列表的Capacity属性怎么样?

它告诉您在列表的内部数据结构中预先分配了多少空间。它是列表在分配更多内存之前可以存储的项目数量。

答案 1 :(得分:6)

Count中的List<T>属性 - 以及BCL中的所有其他ICollection<T>实现 - 是一个O(1)操作,这意味着它快速且独立于列表中的元素数量。

还有一种可以在任何Count()上调用的扩展方法IEnumerable<T>。此方法为O(n),这意味着它的运行时间取决于可枚举中的元素数。但是,有一个例外:如果可枚举实际上是ICollection<T>ICollection的实现,则它使用Count属性使其再次成为O(1)操作。


Capacity属性通常无需担心。

答案 2 :(得分:2)

请改用此代码:list.Any()。它可能比List<>.Count慢,但适用于任何IEnumerable&lt;&gt;以最有效的方式。

Capacity可能比Count更受欢迎。当您计划稍后添加大量项目时使用它。

List.Count的实现如下(实际上是O(1)):

public int Count
{
  get
  {
    return this._size; // this is a field
  }
}

答案 3 :(得分:2)

Count上的O(1)运算。

这是最快的方式。

计数:这实际上是列表中的一些元素。

Capcity :解释更好的文档:

  

获取或设置内部数据结构的元素总数   可以在不调整大小的情况下持有。

答案 4 :(得分:1)

容量不会告诉您列表中有多少对象 - 列表准备好了多少。

来自MSDN:

Capacity is the number of elements that the List<T> can store before resizing is required, while Count is the number of elements that are actually in the List<T>.

List.Count是超快的,是一个被访问的属性,而List.Count()来自IEnumerable,我相信必须通过列表进行完整的枚举。