当我们.ToList()为 an 执行时IEnumerable,列表可能会在扫描 时重新分配,IEnumerable因为它预先不知道大小。如果已知大小,是否有一种简单的方法可以避免性能损失?List使用所需容量初始化 a然后将其复制IEnumerable到其中的效果如何?理想情况下像.ToList(capacity)(不存在)一样简单。
das*_*ght 10
在当容量的一部分的情况下IEnumerable<T>,这也是一个ICollection<T>,该库将分配在正确的能力。
这是 的参考实现List<T>(IEnumerable<T> source),在调用时会调用ToList():
public List(IEnumerable<T> collection) {
if (collection==null)
ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
Contract.EndContractBlock();
ICollection<T> c = collection as ICollection<T>;
if( c != null) {
int count = c.Count;
if (count == 0) {
_items = _emptyArray;
} else {
_items = new T[count];
c.CopyTo(_items, 0);
_size = count;
}
} else {
_size = 0;
_items = _emptyArray;
// This enumerable could be empty. Let Add allocate a new array, if needed.
// Note it will also go to _defaultCapacity first, not 1, then 2, etc.
using(IEnumerator<T> en = collection.GetEnumerator()) {
while(en.MoveNext()) {
Add(en.Current);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
请注意构造函数在collection实现时的行为ICollection<T>:它不是迭代内容并Add为每个项目调用,而是分配内部_items数组,并将内容复制到其中而不重新分配。
在容量未嵌入到类实现中的情况下IEnumerable<T>,您可以使用标准方法的组合轻松地自己定义一个:
public static class ToListExtension {
public static List<T> ToList<T>(this IEnumerable<T> source, int capacity)
{
var res = new List<T>(capacity);
res.AddRange(source);
return res;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
684 次 |
| 最近记录: |