在LINQ结果上将IEnumerable <t>转换为List <t>,造成巨大的性能损失</t> </t>

时间:2010-01-29 14:16:39

标签: c# linq generics .net-4.0 c#-4.0

在你喜欢的LINQ结果上:

var result = from x in Items select x;
List<T> list = result.ToList<T>();

然而,ToList<T>真的很慢,是否会使列表变得可变,因此转换速度很慢?

在大多数情况下,我可以设法只拥有IEnumerableParalell.DistinctQuery,但现在我想将项目绑定到DataGridView,因此我需要的不是{{1}关于如何在ToList或任何替换上获得性能的建议?

IEnumerable的10万条记录中,IEnumerable大约需要6秒钟。

4 个答案:

答案 0 :(得分:10)

.ToList() what 相比速度较慢?

如果您正在比较

var result = from x in Items select x;
List<T> list = result.ToList<T>();

var result = from x in Items select x;

你应该注意,因为懒惰地评估查询,所以第一行根本没有做太多。它不会检索任何记录。 延迟执行使此比较完全不公平

答案 1 :(得分:7)

这是因为LINQ喜欢懒惰并尽可能少地工作。这一行:

var result = from x in Items select x;

尽管您选择了名称,但实际上并不是结果,它只是一个查询对象。它不会获取任何数据。

List<T> list = result.ToList<T>();

现在您实际上已经请求了结果,因此它必须从源中获取数据并制作它的副本。 ToList保证复制。

考虑到这一点,第二行比第一行慢得多并不奇怪。

答案 2 :(得分:2)

不,它没有创建需要时间的列表,它正在获取需要时间的数据。

您的第一个代码行实际上并未获取数据,它只设置一个能够获取数据的IEnumerable。当你调用ToList方法时它实际上会获得所有数据,这就是所有执行时间都在第二行的原因。

您还应该考虑在网格中有一千万行是否有用。没有任何用户可以查看所有行,所以没有任何意义来获取它们。也许你应该提供一种在获取任何数据之前过滤结果的方法。

答案 3 :(得分:0)

我认为这是因为内存重新分配:ToList无法预先知道集合的大小,因此它可以分配足够的存储空间来保存所有项目。因此,它必须在List<T>增长时重新分配。

如果您可以估计结果集的大小,使用List<T>(int)构造函数重载预分配足够的元素,然后手动向其添加项目会快得多。