11

我经常写这样的代码:

if ( list.Count > 0 ) { }

这有效率吗?这个操作看起来像:

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

或者像这样:

  • 检索列表中存储的元素数(986,000)
  • 986,000 是否大于 0?
  • 返回真

也就是要获取列表中的元素个数,是要一直数到列表,还是在某处记录了元素个数?这是所有ICollection课程的情况吗?

Capacity清单的呢?

4

5 回答 5

33

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

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

现在有一个你没有问的问题:

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

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

这不是令人难以置信的低效吗?

是的。

什么会更有效率?

if (sequence.Any())

为什么这样更有效率?

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

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

列表的Capacity属性如何?

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

于 2012-04-13T14:44:30.403 回答
6

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

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


Capacity物业通常无需担心。

于 2012-04-13T14:40:12.593 回答
2

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

Capacity可以大于Count。当您计划稍后添加大量项目时使用它。

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

public int Count
{
  get
  {
    return this._size; // this is a field
  }
}
于 2012-04-13T14:37:44.417 回答
2

Count 是O(1)对 List 的操作。

这是可能的最快方式。

Count:这是列表中实际存在的元素数量。

Capcity:解释更好的文档:

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

于 2012-04-13T14:39:47.697 回答
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,我相信必须对列表进行完整的枚举。

于 2012-04-13T14:39:58.307 回答