Closed
Description
The reason for this goes from here: ncalc/ncalc#408
The FEC fast-compiled code is 2x slower to the result of the System, Compile.
The expression in question:
var e = new System.Linq.Expressions.Expression[11]; // the unique expressions
var expr = Lambda<Func<bool>>(
e[0] = MakeBinary(ExpressionType.Equal,
e[1] = MakeBinary(ExpressionType.Equal,
e[2] = MakeBinary(ExpressionType.Add,
e[3] = Constant(1),
e[4] = Constant(2)),
e[5] = MakeBinary(ExpressionType.Add,
e[6] = Constant(5),
e[7] = Constant(-2))),
e[8] = MakeBinary(ExpressionType.Equal,
e[9] = Constant(42),
e[10] = Constant(42))), new ParameterExpression[0]);
The Jitted assembly printed by BDN is almost the same.
I have a couple of ideas to try:
- System [
Closure
](From my recent benchmark, here is the jitted (highly optimized code) of the delegate compile from expression:
) is the sealed class with the 2 array fields, vs. FECArrayClosure
is the unsealed class (has other specialized inherent variants) with a single array field. The idea is toseal
it and see how the access changed. - Don't use a closure and compile to the static delegate. Previously (on the older .NET versions) this variant was slower than an instance delegate with the empty closure. Maybe something changed.
- Benchmark on .NET 9
Additionally, given that FEC inspects the expression anyway to produce the IL. It may as well optimize logical expressions and avoid emitting the dead code. Minimizing the produced IL (less allocation) and less code size, less work for Jit, etc.