-
Notifications
You must be signed in to change notification settings - Fork 4.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add cheap/fast path for MethodBase.Invoke for use in expression interpreter #6686
Comments
CC @atsushikan @danmosemsft |
Rather than an ad-hoc fix just for Type.Missing, why not a BindingFlags.NoConversion bit to disable all of CheckArguments() weird convenience casting altogether? In another words, all passed in parameters must be the exact type already. Hence, removes Reflection's internal need to mutate (and hence copy) the argument array. No more overhead for all those checks that CheckArguments() must do - the new bit converts Invoke() into a simpler, faster and more predictable api. Note that any budgeting for this has to account for corert which has a completely different implementation of Reflection. |
I'd like this very much, especially for high performance scenario's that have no other way than to depend on reflection (like interpreters) |
For case 1 (pass Type.Missing directly -- no default value) a new API is necessary to opt-in to that functionality. For case 2 (avoid a copy of the incoming array) assume #12832 will address that. |
For case 1 (Type.Missing) the original sample in https://github.com/dotnet/corefx/issues/4112 is now working; not sure what was changed in expressions to allow that. Expression<Action> f = () => Console.WriteLine(Type.Missing);
// Prints System.Reflection.Missing
f.Compile()();
// Prints System.Reflection.Missing (NOW WORKS THE SAME AS ABOVE)
f.Compile(true)(); For case 2 (perf) we are actively working on perf. An IL Emit path was added in 7.0 and new APIs that avoid the object[] allocation are expected in 8.0. |
The expression interpreter in
System.Linq.Expressions
usesInvoke(object, object[])
onMethodBase
when interpretingMethodCallExpression
,NewExpression
, etc. One place is here, in the context of a commit to avoid array copies on our side of the call.The current approach suffers from a few limitations due to the lack of control over the reflection behavior. Culprits are in
MethodBase.CheckArguments
:Type.Missing
can't be passed as-is, these get rewritten to the default value for the parameter (see https://github.com/dotnet/corefx/issues/4112)Case 1 is a functional regression from the expression tree compiler. Case 2 is a heavy source of allocations (think of expression trees having loops) and we don't have to worry about any in-place mutations of the array (i.e. we can transfer ownership altogether).
We'd like a fast path for the expression interpreter to take. Questions:
[InternalsVisibleTo]
toSystem.Linq.Expressions
acceptable?Some possible APIs (public or not) are listed below.
Option 1 - InvokeFast variant
An API that suppresses both behaviors and claims to be "fast"; this is really all we'd need for the expression interpreter:
Option 2 - BindingFlags additions
An API addition to
BindingFlags
and no changes toInvoke
at all (but we'd need access to the verbose overload to use that one in the interpreter):I can noodle around with this if we reach some agreement on the need and ideally the shape.
The text was updated successfully, but these errors were encountered: