Is there a way to analyze how a specific Linq-to-objects query would be executed?

I've written Linq in the past for SQL queries that didn't run well. Using SQL Profiler (or similar), I can watch my query translate to SQL by intercepting it in the database.

Is there a way to do this with Linq queries that work exclusively on objects?

As an example, consider the following Linq query on a list of edges in a directed graph:

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

      

This code is to select all edges that start at the current node, except those that might result in a dead edge.

Now I have a suspicion that this code is ineffective, but I have no idea how to prove it other than analyzing the generated MSIL. I would rather not do this.

Does anyone know how I can do this without SQL?

Edit:

When I talk about inefficiency, I mean inefficiency in terms of "Big O" notation or asymptotic notation. In the example above, is this code doing Linq in O (n) or O (n log m) or even O (nm)? In other words, what is the complexity of the execution path?

With Linq to SQL, I could see (for example) that the second where clause translates to a subquery that is executed for each edge, rather than a more efficient join. I can decide not to use Linq in this case, or at least change Linq to be more efficient with large datasets.

Edit 2:

Found this post - not sure how I missed this in the first place. Just looking for the wrong thing I'm guessing :)

+2


source to share


1 answer


I don't think you need a profiler for this ...

Linq to SQL (or Linq to Entities) queries are translated to another language (SQL) and then executed using an optimized execution plan, so it is difficult to understand exactly how it happens; a profiler may be helpful for such a scenario. On the other hand, Linq to Objects queries are not translated, they are executed "as is". A Linq to Objects query using syntax like SQL is just syntactic sugar for a series of method calls. In your case, the complete request form will look like this:



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

      

So, basically, you are iterating over Edges

, and for each item in, Edges

you are iterating over deadEdges

. Thus, the complexity is here O(n.m)

, where n

is the number of elements in Edges

, and the m

number of elements indeadEdges

+1


source







All Articles