list.count 是不是物理地遍历列表以对其进行计数,或者它是不是保留一个指针
Posted
技术标签:
【中文标题】list.count 是不是物理地遍历列表以对其进行计数,或者它是不是保留一个指针【英文标题】:Does list.count physically iterate through the list to count it, or does it keep a pointerlist.count 是否物理地遍历列表以对其进行计数,或者它是否保留一个指针 【发布时间】:2014-08-22 10:21:38 【问题描述】:我正在逐步浏览大量对象,以针对列表中的所述对象做一些事情。
在我的迭代过程中,我将根据某些条件从列表中删除一些对象。
完成后,我需要根据列表中的对象数量更新 UI。 (T列表)。
问题:
当我调用 list.count 时,.net 是否实际上会遍历列表以 计数,还是将计数存储为属性/变量?
如果 .net 物理地重新遍历列表,我不妨在自己的列表中保留一个计数器,并节省开销?
谢谢
【问题讨论】:
referencesource.microsoft.com/#mscorlib/system/collections/… 【参考方案1】:您同时使用 vb.net 和 c# 标记了您的问题,因此在回复“如果 .net 物理地重新遍历列表,我不妨在自己的列表中保留一个计数器,并保存开销?”
如果您的迭代使用For i = first To last
,那么VB.NET 将在进入循环时评估first
和last
:
Dim first As Integer = 1
Dim last As Integer = 3
For i = first To last
Console.Write(i.ToString() & " ")
last = -99
Next
输出:1 2 3
如果您在 C# 中执行等效操作,则每次迭代都会评估 first
和 last
:
int first = 1;
int last = 1;
for (int i = first; i <= last; i++)
Console.Write(i.ToString() + " ");
last = -99;
输出:1
如果您的 .Count() 函数/属性的评估成本很高和/或您不希望在每次迭代时重新评估它(出于其他原因),那么在 C# 中您可以将其分配给临时变量。
【讨论】:
【参考方案2】:List
被实现为一个数组列表,它跟踪自己的大小,因此调用.Count
属性不需要任何迭代。
如果您调用 LINQ .Count()
扩展方法,这将检查底层 IEnumerable<>
是否实现 ICollection
(List<>
会实现),并尽可能在该接口上使用 .Count
属性。所以这也不会导致任何迭代发生。
顺便说一句,如果您在迭代列表时尝试从列表中删除项目,您将会遇到其他问题。当您从迭代器下删除元素时,迭代的行为方式并不清楚,因此List<>
s 将通过在列表自其枚举器创建以来已被修改时抛出异常来完全避免此问题。
【讨论】:
任何链接,代码来备份您的声明? (我知道这是真的) @L.B:我正在处理它,但看起来其他人在我之前提供了这些链接。 知道了:“首先,发布一个快速占位符答案,然后改进它”【参考方案3】:如备注标签下所述 http://msdn.microsoft.com/en-us/library/27b47ht3(v=vs.110).aspx
检索此属性的值是一个 O(1) 操作。
这意味着没有迭代发生。
【讨论】:
【参考方案4】:它只是保持一个内部 int 来跟踪项目的数量。所以没有迭代。 文档说检索 Count 是一个 O(1) 操作:
http://msdn.microsoft.com/en-us/library/27b47ht3%28v=vs.110%29.aspx
你可以自己看看:
http://referencesource.microsoft.com/#mscorlib/system/collections/generic/list.cs
【讨论】:
【参考方案5】:您可以使用反编译器(例如免费提供的 ILSpy)来回答这些问题。如果您指的是List<T>
类型,那么Count
getter 只涉及读取一个字段:
public int Count
get return this._size;
【讨论】:
以上是关于list.count 是不是物理地遍历列表以对其进行计数,或者它是不是保留一个指针的主要内容,如果未能解决你的问题,请参考以下文章
声纳问题:删除此“\”,添加另一个“\”以对其进行转义,或将其设为原始字符串