Mig*_*elo 16 .net reflection reflection.emit propertyinfo
为什么PropertyInfo获取和设置属性的方法如此之慢?如果我使用构建委托Reflection.Emit,它会快得多.
他们是否正在做一些重要的事情,以便他们采取的时间是合理的?这是...我失去的东西通过Reflection.Emit建立代表,而不是usign的GetValue和SetValue的的PropertyInfo(预留的发展速度)?
PS:请证明,不仅要猜测!
Fab*_*ied 16
的实施RuntimePropertyInfo(这是具体子类PropertyInfo的运行时类型)实现GetValue,并SetValue通过通过反射调用getter和setter方法(MethodInfo.Invoke),而你产生委托可能直接调用方法.因此,问题归结为:RuntimeMethodInfo.Invoke与编译调用相比,为什么这么慢?
当您反编译(或查看参考源)时RuntimeMethodInfo.Invoke,您可以看到这可能是因为Invoke执行了很多任务:
运行时将代理编译为可执行本机代码时,将执行类似的一致性,安全性和可见性检查.它还会发送装箱/拆箱等的代码.但是,它只需要执行一次这些操作,然后可以保证代码可以安全执行.这使得实际方法调用非常便宜的操作(加载参数并跳转到方法地址).
相反,每次调用RuntimeMethodInfo.Invoke(因此对GetValue/ SetValue)都需要重复所有工作,因为上下文 - 参数,实例和返回类型的用法 - 是未知的.这可能就是为什么它如此缓慢.
关于你可能缺少的东西:如果你发出自己的属性调用委托,你当然需要自己处理装箱/拆箱,ref/out参数等.
Fri*_*ied 13
没有必要使用Emit.使用Expression要容易得多.您可以按照SO中的说明加快访问速度 .辅助类为getter或setter创建一个"方法指针"(Action/Func).如果重复使用Action/Func,您将能够像普通的setter一样快速地执行.
// creating setter (once)
var propertyInfo = typeof(T).GetProperty(field);
var setter = FastInvoke.BuildUntypedSetter<T>(propertyInfo));
// usage somehow later in a loop of data
foreach(var myobject in MySource)
{
setter(myobject, myValue)
}
Run Code Online (Sandbox Code Playgroud)