为什么PropertyInfo
获取和设置属性的方法这么慢?如果我使用 构建委托Reflection.Emit
,它会快得多。
他们是否在做一些重要的事情,以便他们花费的时间是合理的?那就是......我是否通过使用Reflection.Emit
构建委托而不是使用 PropertyInfo 的GetValue
和SetValue
(除了开发速度)而遗漏了一些东西?
PS:请举证,不要只凭猜测!
为什么PropertyInfo
获取和设置属性的方法这么慢?如果我使用 构建委托Reflection.Emit
,它会快得多。
他们是否在做一些重要的事情,以便他们花费的时间是合理的?那就是......我是否通过使用Reflection.Emit
构建委托而不是使用 PropertyInfo 的GetValue
和SetValue
(除了开发速度)而遗漏了一些东西?
PS:请举证,不要只凭猜测!
的实现RuntimePropertyInfo
(它是PropertyInfo
运行时类型的具体子类)实现GetValue
并SetValue
通过反射(MethodInfo.Invoke
)调用 getter 和 setter 方法,而您生成的委托可能直接调用这些方法。因此,问题归结为:RuntimeMethodInfo.Invoke
与编译调用相比,为什么这么慢?
当你反编译(或查看参考源)RuntimeMethodInfo.Invoke
时,你可以看到这可能是因为Invoke
执行了很多任务:
运行时将您的委托编译为可执行的本机代码时,将执行类似的一致性、安全性和可见性检查。它还发出装箱/拆箱等代码。但是,它只需要做一次这些事情,然后可以保证代码可以安全执行。这使得实际的方法调用是一个非常便宜的操作(加载参数并跳转到方法地址)。
相反,每次调用RuntimeMethodInfo.Invoke
(因此调用GetValue
/ SetValue
)都需要重复所有工作,因为上下文——参数、实例和返回类型的用法——是未知的。这可能就是它如此缓慢的原因。
关于您可能缺少的内容:如果您发出自己的属性调用委托,您当然需要自己处理装箱/拆箱、引用/输出参数等。
无需使用 Emit。使用表达式要容易得多。您可以按照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)
}