My current understanding is that 'hard coded' code like this:
public int Add(int x, int y) {return x + y;}
will always perform better than expression tree code like this:
Expression<Func<int, int, int>> add = (x, y) => x + y;
var result = add.Compile()(2, 3);
var x = Expression.Parameter(typeof(int));
var y = Expression.Parameter(typeof(int));
return (Expression.Lambda(Expression.Add(x, y), x, y).
Compile() as Func<int, int, int>)(2, 3);
as the compiler has more information and can spend more effort on optimizing the code if you compile it at compile time. Is this generally true?
OK, I have written a little test (probably needs scrutinisation by you experts) but its seems as if expression trees are the fastest (add3), followed by add2 and then add1!
My results debug mode:
My results release mode:
Trying to understand why my build and compiled lambda runs slightly slower than "just delegate" (I think I will need create new SO question for it) I've found this thread and have decided to check the performance using BenchmarkDotNet. Surprise for me: there build manually and compiled lambda is quickest. And yes -there is stable difference between methods.
Results:
I can't make any conclusions from this, it can be difference in IL code or JIT compiler impact.
Code:
Your
Add
function probably compiles to some function overhead (if not inlined) and a single add instruction. Doesn't get any faster than that.Even constructing this expression tree is going to be orders of magnitude slower. Compiling a new function for each invocation is going to be incredibly expensive compared to the direct C# implementation.
Try compiling the function just once and storing it somewhere.
C# 6.0 now allows you to do this:
instead of:
See Method Expressions and Property Expressions
Compilation
The call to
Expression.Compile
goes through exactly the same process as any other .NET code your application contains in the sense that:(the parsing step is skipped because an Expression Tree is already created and does not have to be generated from the input code)
You can look at the source code of the expression compiler to verify that indeed, IL code is generated.
Optimization
Please be aware that almost all of the optimization done by the CLR is done in the JIT step, not from compiling C# source code. This optimization will also be done when compiling the IL code from your lambda delegate to machine code.
Your example
In your example you are comparing apples & oranges. The first example is a method definition, the second example is runtime code that creates a method, compiles and executes it. The time it takes to create/compile the method is much longer than actually executing it. However you can keep an instance of the compiled method after creation. When you have done that, the performance of your generated method should be identical to that of the original C# method.
Consider this case:
So the conclusion one might draw is: IL code is IL code, no matter how it is generated, and Linq Expressions generate IL code.