gpt4 book ai didi

c# - 提高从 MethodCallExpression 获取 MethodInfo 的性能

转载 作者:太空狗 更新时间:2023-10-29 23:47:28 25 4
gpt4 key购买 nike

我们的 UI 系统可以从 MethodInfo 生成表单。在 System.Linq.Expressions 之前,我们使用反射(方法 1)获取 MethodInfo:

MethodInfo info = typeof(ExtensionTestClass).GetMethod("InstanceMethod", BindingFlags.Public | BindingFlags.Instance, null, new Type[] { typeof(string), typeof(string) }, null);

坏处是,如果我们更改 InstanceMethod 的签名或名称,代码仍然可以编译。

输入表达式。现在我们这样做(方法 2):

 MethodInfo info = GetMethod<ExtensionTestClass>(x => x.InstanceMethod("defaultValue", "defaultValue"));

或者这个(方法 3):

MethodInfo info = GetMethod<ExtensionTestClass, string, string>(x => x.InstanceMethod);

语法“更好”,我们得到智能感知,如果方法不存在或签名不匹配,我们会得到编译错误。但是方法2和方法3比反射慢10到20倍左右。

一些数字(用秒表测量):

单次通话:方法一:.0000565方法二:.0004272方法三:.0019222

100000 次调用:方法一:.1171071方法二:1.5648544方法三:2.0602607

我们实际上并没有编译或执行表达式,如果有人对性能差异有任何解释,我很感兴趣。

更新:GetMethod<> 代码:

方法二:

public static MethodInfo GetMethod<T>(Expression<Action<T>> target)
{
MethodCallExpression exp = target.Body as MethodCallExpression;
if (exp != null)
{
return exp.Method;
}
return null;
}

方法三:

public static MethodInfo GetMethod<T, A1, A2>(Expression<Func<T, Action<A1, A2>>> expression)
{
var lambdaExpression = (LambdaExpression)expression;
var unaryExpression = (UnaryExpression)lambdaExpression.Body;
var methodCallExpression = (MethodCallExpression)unaryExpression.Operand;
var methodInfoExpression = (ConstantExpression)methodCallExpression.Arguments.Last();
return (MethodInfo)methodInfoExpression.Value;
}

最佳答案

我的猜测是它比较慢,因为表达式版本执行相同的反射(尽管它们可能使用 IL 快捷方式 methodof,这在 C# 中没有类似物)以创建表达式树,除了为每次调用创建树本身的开销(我不认为它们被编译器发出的代码缓存);另外,您还必须读取这些树才能使该方法退出。

反射可能“慢”,但实际上它非常快;特别是因为我相信幕后的数据也被缓存了。因此,一旦您调用了 GetMethod,第二次调用会更快。这提供了另一个令人信服的证据,证明为什么后续的表达式树版本变慢了——因为它们实际上做了更多的工作。

如果你对 IL 很满意,编译一个包含所有三个的版本,然后用 ILSpy 或 Reflector 分析编译后的图像(在 C# 模式下,两者都会很聪明,并将表达式代码重新构造回 C#,这是不好的; 所以切换到 IL 模式)——看看为生成表达式树而发出的代码,您就会明白我的意思。

关于c# - 提高从 MethodCallExpression 获取 MethodInfo 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10306485/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com