sklose/NCalc2

Allow to operate on System.Linq.Expressions.Expression

Closed this issue · 11 comments

Currently Expression.ToLambda returns Func<>
Intermediate expression is hidden and not avaiable to touch
LambdaExpressionVistor is internal

I need a way to use generated System.Linq.Expressions.Expression for my needs
Thank you.

If you provide appropriate way on how to achieve this, I could make merge request

Can you explain your use case? The things you've listed seem like they're what's blocking you from achieving something, but I'd like to know what you want to do.

Hi
My use case it to get intermediate System.Linq.Expressions.Expression if I need
Currently I can get only NCalc2.Expression or Func<>
I need this to pass to optimizator of System.Linq.Expressions.Expression if I need

Currently I solved it by forking and changing LambdaExpressionVistor to public, duplication ToLambda method on my side to obtain intermediate result

We could easily have another function on Expression that returns the ExpressionTree one step short of compiling it. However, I don't full understand the use case for it. You mentioned something about an optimizer, could you elaborate on that? In general I would consider it a bug if our lambda isn't optimal, and I'd rather ensure we generate an optimal lambda instead of adding the function that gives you access to the underlying ExpressionTree.

Here is my test project, where you can check the behavior of generated expression online
https://eugenca.github.io/wasm_projects/runge-kutta/
This is my setup:
image
On screenshot you could see parameters used to make execution for about 1000ms, and formula. In dev console you may see that formula contains additions to context variable, which are not optimized after compilation. (see "expression: ((((ctx.x + 2) + 2) + 2) + 2)" string)
I used https://github.com/Thorium/Linq.Expression.Optimizer to optimize it.
The issue I spotted was the fact that formula x+100 is faster than identical formula x+2+2+2 ... +2+2 (50 times +2)

however formula 2+2+ ... +2 is as fast as 100

So in my opinion, optional access to generation of System.Linq.Expressions.Expression may be useful in this or different cases if someone needed

I think it might be valuable to take a dependency on Thorium/Linq.Expression.Optimizer and have it optimize all lambdas. Would be curious to see

  • how much time does it add to the compilation step
  • how much improvement do we get on our existing test cases
  • how much improvement can we get on more niche/academic cases

We can in addition add another API that exposes the ExpressionTree to the user.

happy to review a PR if you wanna give it a go @eugenca

I would add function to expose System.Linq.Expressions.Expression