3 回答
TA贡献1796条经验 获得超4个赞
IEnumerable.ToList()
是的,IEnumerable<T>.ToList()确实会对性能产生影响,尽管可能只需要关注性能关键的操作,但它是O(n)操作。
该ToList()操作将使用List(IEnumerable<T> collection)构造函数。这个构造函数必须复制数组(通常是IEnumerable<T>),否则将来对原始数组的修改T[]也将在源上更改,这通常是不希望的。
我想重申的是,这只会对庞大的列表有所作为,复制内存块是一项非常快速的操作。
方便的提示,AsvsTo
您会在LINQ中注意到有几种以As(如AsEnumerable())和To(如ToList())开头的方法。开头的方法To需要进行上述转换(即可能会影响性能),而开头的方法As则不需要,只需要进行一些强制转换或简单操作即可。
有关的其他详细信息 List<T>
List<T>如果您有兴趣,这里有一些工作原理的详细信息:)
A List<T>还使用一种称为动态数组的结构,该结构需要按需调整大小,此调整大小事件将旧数组的内容复制到新数组。因此,它从很小的地方开始,并在需要时增加尺寸。
这是的Capacity和Count属性之间的区别List<T>。Capacity指的是幕后数组的大小,Count是其中的项目数List<T>始终为<= Capacity。因此,当将一项添加到列表中时,将其增加到之后Capacity,的大小将List<T>增加一倍,并复制数组。
TA贡献1820条经验 获得超10个赞
调用toList()会对性能产生影响吗?
当然是。从理论上讲i++,它甚至会对性能产生影响,可能会使程序变慢几格。
怎么.ToList办?
调用时.ToList,代码将调用Enumerable.ToList()作为扩展方法的return new List<TSource>(source)。在相应的构造函数中,在最坏的情况下,它将遍历item容器并将它们一个接一个地添加到新容器中。因此,它的行为对性能几乎没有影响。成为应用程序的性能瓶颈是不可能的。
问题中的代码有什么问题
Directory.GetFiles遍历该文件夹并将所有文件的名称立即返回到内存中,这有可能会导致string []占用大量内存,从而减慢一切。
那应该怎么办
这取决于。如果您(以及您的业务逻辑)保证该文件夹中的文件数量始终很小,那么该代码是可以接受的。但是仍然建议使用懒惰版本:Directory.EnumerateFiles在C#4中。这更像是查询,不会立即执行,您可以在其上添加更多查询,例如:
Directory.EnumerateFiles(myPath).Any(s => s.Contains("myfile"))
一旦找到名称包含“ myfile”的文件,它将立即停止搜索路径。这显然具有更好的性能.GetFiles。
TA贡献1775条经验 获得超8个赞
调用toList()会对性能产生影响吗?
就在这里。使用扩展方法Enumerable.ToList()
将从源集合构造一个新List<T>
对象,IEnumerable<T>
这当然会对性能产生影响。
但是,了解List<T>
可能会帮助您确定性能影响是否重大。
List<T>
使用数组(T[]
)存储列表的元素。数组一旦分配就无法扩展,因此List<T>
将使用超大数组来存储列表中的元素。当List<T>
增长超出基础数组的大小时,必须分配新数组,并且必须在列表可以增长之前将旧数组的内容复制到新的较大数组。
List<T>
从中构造新对象时,IEnumerable<T>
有两种情况:
源集合的实现
ICollection<T>
:然后ICollection<T>.Count
用于获取源集合的确切大小,并在使用ICollection<T>.CopyTo()
。将源集合的所有元素复制到支持数组之前分配一个匹配的支持数组。此操作非常有效,可能会映射到某些CPU指令以复制内存块。但是,就性能而言,新阵列需要内存,复制所有元素需要CPU周期。否则源集合的大小是未知的,并且使用的枚举器
IEnumerable<T>
将每个源元素一次添加到新元素中List<T>
。最初,支持数组为空,并创建了大小为4的数组。然后,当此数组太小时,其大小将增加一倍,因此后备数组将像4、8、16、32等那样增长。每当后备数组增长时,都必须重新分配它,并且必须复制到目前为止存储的所有元素。与可以立即创建正确大小的数组的第一种情况相比,此操作的成本要高得多。另外,如果您的源集合包含33个元素,则该列表最终将使用64个元素的数组浪费一些内存。
在您的情况下,源集合是一个实现的数组,ICollection<T>
因此,除非源数组很大,否则您不必担心性能影响。调用ToList()
将只复制源数组并将其包装在一个List<T>
对象中。即使是第二种情况的性能,也不必为小收藏而担心。
- 3 回答
- 0 关注
- 1036 浏览
添加回答
举报