This question already has answers here:
Is there a performance impact when calling ToList()?

(8个答案)


3年前关闭。




与我合作的许多开发人员对使用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()方法的效率如何?假设内容为POCO,它会创建一个新列表,并占用多少内存?如果它是值类型而不是POCO,这会改变吗?
  • 列表的大小将决定效率,还是列表的大小不决定ToList()的成本?
  • 如果将列表强制转换为IEnumerable,然后在其上调用ToList(),它将仅返回原始对象吗?

  • P.s.我知道一次使用ToList不会给您带来任何麻烦,但是我们正在构建一个高度并发的系统,该系统当前受CPU限制,因此我希望获得一些小的成功,如果扩展的话,将会带来很大的改进

    最佳答案


    ToList()方法通过创建新列表并使用给定集合的项填充列表来具体化给定集合。 Linq.ToList() implementation:

    public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source) {
        if (source == null) throw Error.ArgumentNull("source");
        return new List<TSource>(source);
    }
    

    这样一来,您将无法获得延期执行的能力(如果需要)



    当它调用List的副本构造函数并创建一个新列表时,它将在每个项目上工作。因此它将以O(n)运行-这意味着列表的大小很重要。有关副本构造函数的操作的MSDN文档:



    正如@Jason在下面的评论中所提到的,Copy构造函数很聪明并且很有效,但是在不需要时仍然可以执行O(n)操作,而不必执行



    不会。它将创建一个新列表,如上所示

    至于您的示例代码:
    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()

    关于c# - ToList()的效率,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/46219166/

    10-13 03:25