为什么获取和设置属性的PropertyInfo
方法这么慢?如果使用Reflection.Emit
构建委托,则速度会更快。
他们是否在做重要的事情,以便花时间证明自己是正确的?那就是...我是否通过使用Reflection.Emit
来构建委托而不是使用PropertyInfo的GetValue
和SetValue
来缺少某些东西(除了开发速度之外)?
PS:请提供证据,而不仅仅是猜测!
最佳答案
RuntimePropertyInfo
的实现(这是运行时类型的PropertyInfo
的具体子类)通过反射(GetValue
)调用getter和setter方法来实现SetValue
和MethodInfo.Invoke
,而生成的委托可能会调用方法直接。因此,问题归结为:与编译调用相比,为什么RuntimeMethodInfo.Invoke
这么慢?
当您对RuntimeMethodInfo.Invoke
进行反编译(或查看其参考源)时,您会发现这可能是因为Invoke
执行许多任务:
它执行一致性检查(所传递的参数的数量和类型是否与签名匹配?所传递的实例是否与声明类型相匹配?尽管方法是静态的,但仍是所传递的实例),
它执行可见性和(如果避免了可见性检查)安全性检查,
它会解开parameter数组,以特殊方式处理ref参数,以便可以将它们写回以后,
它会在必要时取消对参数的装箱,
它需要根据运行时类型句柄和与RuntimeMethodHandle关联的方法句柄找到方法指针,然后调用该方法,
如果需要,它将装箱返回值,并且
它将所有引用/输出参数放入框并将其放入参数数组。
当运行时将委托编译为可执行的本机代码时,它将执行类似的一致性,安全性和可见性检查。它还会发出用于装箱/拆箱等的代码。但是,它只需要执行一次这些操作,然后就可以保证代码可以安全执行。这使实际的方法调用变得非常便宜(加载参数并跳转到方法地址)。
相反,由于不知道上下文(参数,实例和返回类型的用法),因此每次对RuntimeMethodInfo.Invoke
(因此对GetValue
/ SetValue
)的调用都需要重复所有工作。这可能就是为什么它这么慢的原因。
关于可能缺少的内容:如果发出自己的属性调用委托,那么您当然需要自己处理装箱/拆箱,ref / out参数等。
关于.net - 为什么PropertyInfo SetValue和GetValue这么慢?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/12767091/