0

I need to build a dynamic query that can query a large list of objects and get the objects which satisfy a complex predicate known at runtime. I know I want to do it upfront and pass it into the collection to filter on, rather than create some complex switch case on the collection itself.

Everything points me to Expressions and Predicate Builder, which I'm happy to use to chain together expressions in a loop like:

Expression<Func<MyObject, bool>> query = PredicateBuilder.True<MyObject>();
query = query.And(x => x.Field == passedInSearchCriterion)

but I could also do that with:

Func<MyObject, bool> query = x => true;
query = x => query(x) && (x => x.Field == passedInSearchCriterion)

I know the first is better in the case of LINQ to SQL converting it to SQL to execute in the database etc when given to entity framework or something.

But say they were both run locally, not in a database, on a large list, is there any performance difference then in terms of how the resulting function is executed?

  • I think your first example is more 'normal' C# (you see this kind of construct in many code bases). As for performance benefits, you should do your own testing as it probably depends more on your data structures than anything else (Benchmark.NET or similar will help with measuring performance). – Neil Apr 08 '21 at 11:30
  • 1
    With LINQ to Objects only, the `Expression` variant should be slightly slower because it has to be compiled at runtime, as opposed to having delegates compiled ahead of time. The difference is likely to be negligible however, and readability and generality are more important (depending on what's actually needed). See also [the recommended reading on "what is faster"](https://ericlippert.com/2012/12/17/performance-rant/) questions. – Jeroen Mostert Apr 08 '21 at 11:30
  • @JeroenMostert I prefer the look of the expression variant, it seems clearer. I just wondered if there was a more specific reason that I never see the second variant, even in cases where the collection is already in memory. I also read in another answer that 'composing Func is inefficient compared to composing Expression as you are building increasingly nested lambda method calls instead of a flat expression body'. – Jack Jacques Apr 08 '21 at 12:00

1 Answers1

0

I know the first is better because of LINQ to SQL converting it to SQL to execute in the database etc when given to entity framework or something.

No, you don't "know" it's better because you don't understand the difference between expressions and delegates.

That main difference is that expressions are effectively descriptions of a piece of code, and can be inspected to find out information like parameter names - this is why ORMs use them, to map POCOs to SQL columns - while delegates are nothing more than pointers to a method to be executed. As such, there are optimizations the C# compiler can perform on delegates, which it cannot do for expressions. Further details here.

So yes, there will be a performance difference, almost certainly in favour of delegates. Whether that difference is quantifiable and/or relevant to your use-case is something only you can determine via benchmarks.

But any performance difference is irrelevant anyway, because you don't need expressions for your use-case. Just use delegates, which will always be faster.

Ian Kemp
  • 28,293
  • 19
  • 112
  • 138
  • I meant I knew it was better in a case where you are calling it on an iqueryable and passing that to SQL. I understand they are not the same, I just wondered if there was any major difference in performance when the expression is compiled into a delegate and run locally. Thanks. – Jack Jacques Apr 08 '21 at 12:10