代码之家  ›  专栏  ›  技术社区  ›  Damovisa

有没有办法分析特定的linq to objects查询将如何执行?

  •  2
  • Damovisa  · 技术社区  · 15 年前

    在过去,我编写了linq到sql的查询,但这些查询没有很好地执行。使用SQL探查器(或类似的),我可以通过在数据库中拦截查询来查询查询是如何翻译成SQL的。

    对于只对对象进行操作的linq查询,有没有办法做到这一点?

    作为一个例子,考虑在有向图的边列表上执行以下linq查询:

    var outEdges = from e in Edges
                   where e.StartNode.Equals(currentNode) &&
                   !(from d in deadEdges select d.StartNode).Contains(e.EndNode)
                   select e;
    

    该代码应该选择从当前节点开始的所有边缘,除了那些可以导致死边缘的边缘。

    现在,我怀疑这段代码效率低下,但除了分析生成的msil之外,我不知道如何证明它。我宁愿不那样做。

    有人知道没有SQL我怎么做到这一点吗?

    编辑:

    当我谈到无效率时,我指的是“大O”符号或渐近符号的无效率。在上面的例子中,执行linq的代码是o(n)还是o(n log m)甚至o(n.m)?换句话说,执行路径的复杂性是什么?

    使用linq to sql,我可能会看到(例如)第二个where子句被转换为一个子查询,该子查询针对每个边运行,而不是一个更有效的连接。在这种情况下,我可能决定不使用linq,或者至少更改linq,这样在处理大型数据集时效率更高。

    编辑2:

    Found this post -不知道我当初是怎么错过的。只是在寻找错误的东西,我想:)

    1 回复  |  直到 15 年前
        1
  •  1
  •   Thomas Levesque    15 年前

    我认为你不需要一个分析工具…

    LINQtoSQL(或LINQ到实体)查询被翻译成另一种语言(SQL),然后使用优化的执行计划执行,因此很难看到究竟发生了什么;对于这种情况,分析器可能是有用的。另一方面,linq to objects查询不会被转换,而是按原样执行。使用类sql语法的linq to objects查询只是一系列方法调用的语法糖。在您的情况下,查询的完整形式是:

    var outEdges = Edges.Where(e => e.StartNode.Equals(currentNode) &&
                               !deadEdges.Select(d => d.StartNode).Contains(e.EndNode));
    

    所以,基本上,你迭代 Edges ,对于中的每个项目 边缘 你重复一遍 deadEdges . 所以这里的复杂性是 O(n.m) 在哪里 n 是中的项目数 边缘 m 中的项目数 退役