LinQ 优化
Posted
技术标签:
【中文标题】LinQ 优化【英文标题】:LinQ optimization 【发布时间】:2011-02-26 14:16:22 【问题描述】:下面是一段代码:
void MyFunc(List<MyObj> objects)
MyFunc1(objects);
foreach( MyObj obj in objects.Where(obj1=>obj1.Good))
// Do Action With Good Object
void MyFunc1(List<MyObj> objects)
int iGoodCount = objects.Where(obj1=>obj1.Good).Count();
BeHappy(iGoodCount);
// do other stuff with 'objects' collection
这里我们看到集合被分析了两次,每次检查每个成员的“好”属性的值:第一次计算好对象的计数,第二次 - 遍历所有好对象。
希望对其进行优化,这里有一个简单的解决方案:
在调用 MyFunc1 之前,makecreate 一个额外的临时集合只包含好的对象(goodObjects,它可以是 IEnumerable); 获取这些对象的计数并将其作为附加参数传递给 MyFunc1; 在“MyFunc”方法中迭代不是通过“objects.Where(...)”而是通过“goodObjects”集合。方法还不错(据我所知),但需要在“MyFunc”方法中创建额外的变量,并且需要传递额外的参数。
问题:是否有任何 LinQ 开箱即用的功能允许在 1st Where().Count() 期间进行任何缓存,记住已处理的集合并在下一次迭代中使用它?
欢迎提出任何想法。
谢谢。
【问题讨论】:
【参考方案1】:不,LINQ 查询没有以这种方式优化(您描述的方式类似于 SQL Server 重用查询执行计划的方式)。 LINQ 没有(并且,出于实际目的,无法)对您的对象了解得足够多,无法以这种方式进行优化。据它所知,您的收藏在两次调用之间发生了变化(或完全不同)。
您显然知道将查询保留到新的 List<T>
中的能力,但除此之外,如果不了解您的课程以及在哪里使用 MyFunc
的更多信息,我真的没有什么可以推荐的。
【讨论】:
【参考方案2】:只要 MyFunc1 不需要通过添加/删除对象来修改列表,这将起作用。
void MyFunc(List<MyObj> objects)
ILookup<bool, MyObj> objLookup = objects.ToLookup(obj1 => obj1.Good);
MyFunc1(objLookup[true]);
foreach(MyObj obj in objLookup[true])
//..
void MyFunc1(IEnumerable<MyObj> objects)
//..
【讨论】:
以上是关于LinQ 优化的主要内容,如果未能解决你的问题,请参考以下文章