17

我被告知使用 Reflection.Emit 而不是 PropertyInfo.GetValue / SetValue,因为这样更快。但我真的不知道 Reflection.Emit 中的哪些内容以及如何使用它来替代 GetValue 和 SetValue。有人可以帮我吗?

4

5 回答 5

26

只是一个替代答案;如果您想要性能,但需要类似的 API - 考虑HyperDescriptor;这Reflection.Emit在下面使用(所以你不必),但在PropertyDescriptorAPI 上暴露自己,所以你可以使用:

PropertyDescriptorCollection props = TypeDescriptor.GetProperties(obj);
props["Name"].SetValue(obj, "Fred");
DateTime dob = (DateTime)props["DateOfBirth"].GetValue(obj);

启用它的一行代码,它处理所有缓存等。

于 2009-11-26T16:40:17.060 回答
23

如果您多次获取/设置相同的属性,那么使用某些东西来构建类型安全的方法确实会比反射更快。但是,我建议使用Delegate.CreateDelegate而不是 Reflection.Emit。它更容易正确,而且速度仍然非常快。

我在我的 Protocol Buffers 实现中使用了它,它与PropertyInfo.GetValue/SetValue. 正如其他人所说,只有在证明最简单的方法太慢之后才这样做。

如果您决定走这条路,我有一篇博文,其中包含更多详细信息。CreateDelegate

于 2009-11-26T15:45:22.463 回答
11

使用 PropertyInfo.GetValue/SetValue

如果您有性能问题缓存 PropertyInfo 对象(不要重复调用 GetProperty)

如果 - 且仅当 - 使用反射是应用程序的性能瓶颈(如分析器中所见),请使用 Delegate.CreateDelegate

如果——而且真的只有当——你绝对确定读/写值仍然是最严重的瓶颈,那么是时候开始学习在运行时生成 IL 的有趣世界了。

我真的怀疑它是否值得,这些级别中的每一个都增加了代码的复杂性,然后它们提高了性能——只有在你必须这样做时才这样做。

如果对属性的运行时访问是您的性能瓶颈,那么编译时访问可能会更好(很难同时获得通用和超高性能)。

于 2009-11-26T15:43:26.787 回答
1

Reflection.Emit 的目的与 PropertyInfo.Get/SetValue 的目的完全不同。通过 Reflection.Emit,您可以直接发出 IL 代码,例如到动态编译的程序集中,并执行此代码。当然,此代码可以访问您的属性。

我严重怀疑这会比最终使用 PropertyInfo 快得多,而且它也不是为此目的而制作的。例如,您可以使用 Reflection.Emit 作为小型编译器的代码生成器。

于 2009-11-26T15:39:45.657 回答
1

使用 Reflection.Emit 似乎有点过于“聪明”,而且是过早的优化。如果您分析您的应用程序,并且您发现 GetValue/SetValue 反射是瓶颈,那么您可以考虑优化,但可能甚至不会...

于 2009-11-26T15:43:22.510 回答