迭代Linq结果时异常缓慢在探索最近的一个Linq问题时,我注意到算法似乎相当慢。深入挖掘我注意到它不是linq代码,但结果的输出需要很长时间。(感谢MarcGravel顺便说一句,我看过最简单的Linq。)代码:DateTimedt=DateTime.Now;Console.WriteLine("算法开始"+dt.Second+"."+dt.Millisecond);varqry=fromlinEnumerable.Range(100000,999999)lets=l.ToString()letsReversed=newstring(s.Reverse().ToArray())fromiinEnumerable.Range(3,9)让t=(l*i).ToString()wheret==sReversedselectnew{l,i};dt=DateTime.Now;Console.WriteLine("算法结束"+dt.Second+"."+dt.Millisecond);foreach(varrowinqry)Console.WriteLine("{0}x{1}={2}",row.l,row.i,row.l*row.i);dt=DateTime.Now;Console.WriteLine("DispEnd"+dt.Second+"."+dt.Millisecond);输出:AlgStart20.257AlgEnd20.270109989x9=989901219978x4=8799121099989x9=9899901DispEnd31.1秒计数并显示超过11?!?是什么原因?原因是查询在被枚举之前不会真正运行。在LINQtoobject中,它只是设置了一堆代理,当您遍历枚举器时将调用这些代理。如果您要将ToList()添加到您的查询中以实现它,您会发现花费的时间将被转移到设置而不是显示上。linq查询似乎执行得很快的原因是因为linq使用延迟执行,所以在定义点实际上没有计算任何东西,即在您开始枚举结果之前不会执行任何“真正的”工作。对于许多linq提供程序,只需将“algstart”解析为“altend”——在结果枚举实际开始之前不会评估实际表达式。因此,“qry”变量的实际创建速度很快(只需设置一个实际执行查询逻辑的枚举),但枚举它的速度较慢。LINQ代码只是根据查询表达式创建查询对象,这不会花费太多时间。只有在foreach中才是真正执行的查询。顺便说一下,您不应该使用DateTime.Now来提高性能,而应该使用Stopwatch类,因为它更准确。查询在迭代之前不会实际计算。在此之前,它就像一条SQL语句,等待执行。这道题是做蛮力的;LINQ在这种情况下实际上非常方便——我在这里讨论了它:Bruteforce(butlazy).这通常使用迭代器块来完成;考虑它们之间的区别:}}and:staticIEnumerableWhere(thisIEnumerabledata,Funcpredicate){varlist=newList();foreach(Titemindata){if(predicate(item))list.Add(item);}返回列表;差异点在于,第二个版本在调用Where时返回所有工作,返回单个结果,其中-第二个版本(通过迭代器块的魔法)仅在枚举器调用MoveNext()时起作用。迭代器块在深度C#中的免费示例的第6章中有更详细的讨论。一般来说,这样做的好处是它使查询可组合——对于基于数据库的查询尤其重要,但对于常规工作同样有效。请注意,即使使用迭代器块,也有第二个考虑因素;缓冲。考虑Reverse()-不管你怎么做,要反转一个序列,首先你需要找到序列的结尾。现在考虑并非所有序列都结束!将此与Where、Skip、Take等进行对比-无需缓冲即可过滤行(只需删除项目)。在无限序列中使用它的一个很好的例子是这个Fibonacci问题,我们可以在其中使用非缓冲延迟方法:foreach(longiinFibonacci().Take(10)){Console.WriteLine(i);}None延迟执行,这永远不会完成。以上就是C#学习教程:StrangeslownesswheniterateLinqresults分享的所有内容,如果对大家有用,需要进一步了解C#学习教程,希望大家多多关注——本文收集自互联网,不代表立场,如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
