与我一起工作的许多开发人员都觉得使用List比使用IEnumerable更舒服(例如)。我想知道是否对ToList()过度使用有任何性能影响。例如,或,将在排序后使用ToList(),以便再次将列表提取出来。
private void ListThinger(List<T> input)
{
input = input.OrderBy(s => s.Thing).ToList();
foreach(var thing in input)
{
// do things
}
}我的问题是:
ToList()方法的效率如何?它会创建一个新的列表吗?假设内容是POCOs的话,这需要多少内存?如果它是一种值类型而不是POCO,这种情况会改变吗?ToList()的成本IEnumerable,然后在它上调用ToList(),那么它会返回原始对象吗?附注:我知道ToList的一次使用不会破坏任何退路,但我们正在构建一个高度并发的系统,目前该系统受CPU的限制,所以我正在寻找一些小的胜利,当进行缩放时,这会带来很大的改进。
发布于 2017-09-14 12:32:16
ToList()方法的效率如何?它会创建一个新的列表吗?假设内容是POCOs的话,这需要多少内存?如果它是一种值类型而不是POCO,这种情况会改变吗?
ToList()方法通过创建新列表并将其填充到给定集合的项来实现给定集合。 implementation
public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
return new List<TSource>(source);
}通过这样做,如果需要的话,您将不会获得执行的权力。
列表的大小将决定效率,还是列表的大小不会决定ToList()的成本?
当它调用List的复制构造函数并创建一个新列表时,它将处理每个项。因此,它将在O(n)中运行--这意味着列表的大小很重要。MSDNs关于复制构造函数操作的文档:
初始化List类的新实例,该实例包含从指定集合复制的元素,并且具有足够的容量来容纳复制的元素数。
正如@Jason在下面的注释中所提到的,复制构造器是智能的并且是高效的,但是在不需要的时候执行它仍然是一个不需要发生的O(n)操作。
如果一个列表被转换成一个IEnumerable,然后在它上调用ToList(),那么它会返回原始对象吗?
不是的。它将创建一个新的列表,如上面所示。
至于您的示例代码:
input = input.OrderBy(s => s.Thing).ToList();
foreach(var thing in input)
{
// do things
}当您得到一个物化列表(而不是可能在执行中执行的IQueriable/IEnumerable )时,在添加后添加ToList不会给您带来任何好处。
您可以在这里查看,也可能有帮助:When to use LINQ's .ToList() or .ToArray()
发布于 2017-09-14 12:35:24
你自己试试看:
var list = new List<int>();
bool areListsTheSame = list == ((IEnumerable<int>)list).ToList();https://stackoverflow.com/questions/46219166
复制相似问题