【问题标题】:LinQ optimizationLinQ 优化
【发布时间】: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() 期间进行任何缓存,记住已处理的集合并在下一次迭代中使用它?

欢迎提出任何想法。

谢谢。

【问题讨论】:

    标签: c# .net linq optimization


    【解决方案1】:

    不,LINQ 查询没有以这种方式优化(您描述的方式类似于 SQL Server 重用查询执行计划的方式)。 LINQ 没有(并且,出于实际目的,无法)对您的对象了解得足够多,无法以这种方式进行优化。据它所知,您的收藏在两次调用之间发生了变化(或完全不同)。

    您显然知道将查询保留到新的 List&lt;T&gt; 中的能力,但除此之外,如果不了解您的课程以及在哪里使用 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)
      {
        //..
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-04-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-08-17
        相关资源
        最近更新 更多