在你喜欢的LINQ结果上:
var result = from x in Items select x;
List<T> list = result.ToList<T>();
然而,ToList<T>
真的很慢,是否会使列表变得可变,因此转换速度很慢?
在大多数情况下,我可以设法只拥有IEnumerable
或Paralell.DistinctQuery
,但现在我想将项目绑定到DataGridView,因此我需要的不是{{1}关于如何在ToList或任何替换上获得性能的建议?
在IEnumerable
的10万条记录中,IEnumerable
大约需要6秒钟。
答案 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)
构造函数重载预分配足够的元素,然后手动向其添加项目会快得多。