我经常写这样的代码:
if ( list.Count > 0 ) { }
效率这么高吗?此操作是否如下所示:
或者像这样:
也就是说,为了获得列表中的元素数量,您是否必须在列表中一直计算,或者是在某处记录的元素数量?这是所有ICollection
类的情况吗?
列表的Capacity
怎么样?
答案 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,我相信必须通过列表进行完整的枚举。