linq - 使用 Any() 时优化 OrderBy()

标签 linq optimization linq-to-objects

所以我有一个相当标准的 LINQ-to-Object 设置。

var query = expensiveSrc.Where(x=> x.HasFoo)
                        .OrderBy(y => y.Bar.Count())
                        .Select(z => z.FrobberName);    

// ...

if (!condition && !query.Any())
 return; // seems to enumerate and sort entire enumerable 

// ...

foreach (var item in query)
   // ...

这将所有内容枚举两次。哪个不好。
var queryFiltered = expensiveSrc.Where(x=> x.HasFoo);

var query = queryFiltered.OrderBy(y => y.Bar.Count())
                         .Select(z => z.FrobberName); 

if (!condition && !queryFiltered.Any())
   return;

// ...

foreach (var item in query)
   // ...

有效,但有更好的方法吗?

是否有任何非疯狂的方式来“启发” Any() 绕过非必需的操作?我想我记得这种优化进入 EduLinq。

最佳答案

为什么不直接去掉多余的:

if (!query.Any())
 return; 

它似乎真的没有任何用途——即使没有它,foreach 的主体如果查询没有结果,则不会执行。所以使用 Any() checkin ,您在快速路径中不保存任何内容,并在慢速路径中枚举两次。

另一方面,如果您必须知道循环结束后是否找到任何结果,您不妨只使用一个标志:
bool itemFound = false;

foreach (var item in query)
{
    itemFound = true;
    ... // Rest of the loop body goes here.
}

if(itemFound)
{
   // ...
}

或者,如果您真的担心循环体中的冗余标志设置,您可以直接使用枚举器:
using(var erator = query.GetEnumerator())
{
    bool itemFound = erator.MoveNext();

    if(itemFound)
    {
       do
       {
           // Do something with erator.Current;
       } while(erator.MoveNext())
    }

   // Do something with itemFound
}

关于linq - 使用 Any() 时优化 OrderBy(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8980806/

相关文章:

c# - 如何在linq to sql中分组?

c# - 将存储过程与 LINQ 结合使用

Java枚举实践中,不好的代码需要改进

c++ - 平方差和的SSE优化

c# - 聚合值直到达到限制

c# - 如果其中一个属性为 NULL,则此 LINQ 语句会崩溃。我怎样才能解决这个问题?

c# - Entity Framework 中 Select 和 Where 之间的区别

php - Wordpress 仅在主页上做什么(加载缓慢)?

c# - LINQ GroupBy 并选择不同的属性

c# - C# 中是否有 std::for_each 算法模拟(Linq to Objects)