Joa*_*nge 1 .net c# linq performance ienumerable
我正在使用一些LINQ select东西来创建一些返回的集合IEnumerable<T>.
在我的情况下,我需要一个List<T>,所以我将结果传递给List<T>构造函数来创建一个.
我想知道这样做的开销.我的收藏中的项目通常是数百万,所以我需要考虑这个.
我假设,如果IEnumerable<T>包含ValueTypes,它是最糟糕的表现.
我对吗?Ref类型怎么样?无论哪种方式,还有List<T>.Add一百万次通话的费用,对吗?
有办法解决这个问题吗?像我可以使用扩展方法"重载"LINQ Select等方法吗?
最好避免使用列表.如果你可以使用IEnumerable <T>保持你的来电者,你会省去一些麻烦.
LINQ的ToList()将使用您的枚举,并使用List <T>(IEnumerable <T>)构造函数直接从它构造一个新的List <T>.这与自己制作列表相同,性能明智(尽管LINQ也进行了空检查).
如果您自己添加元素,请使用AddRange方法而不是Add.ToList()与AddRange非常相似(因为它使用了带有IEnumerable <T>的构造函数),在这种情况下,这通常是你最好的选择.
没有,有元素类型存在价值的类型没有特别的惩罚,假设你使用IEnumerable<T>的替代IEnumerable.你不会得到任何拳击.
如果您事先确实知道结果的大小(Select可能不会导致结果),您可能需要考虑使用该大小的缓冲区创建列表,然后使用AddRange添加值.否则,列表必须在每次填充缓冲区时调整其缓冲区大小.
例如,而不是做:
Foo[] foo = new Foo[100];
IEnumerable<string> query = foo.Select(foo => foo.Name);
List<string> queryList = new List<string>(query);
Run Code Online (Sandbox Code Playgroud)
你可能会这样做:
Foo[] foo = new Foo[100];
IEnumerable<string> query = foo.Select(x => x.Name);
List<string> queryList = new List<string>(foo.Length);
queryList.AddRange(query);
Run Code Online (Sandbox Code Playgroud)
您知道调用Select将生成与原始查询源相同长度的序列,但据我所知,执行环境中没有任何内容具有该信息.