Reflection.Emit 比 GetValue 和 GetValue 更好设置值:S

发布于 2024-08-12 18:10:18 字数 151 浏览 3 评论 0原文

我被告知使用 Reflection.Emit 而不是 PropertyInfo.GetValue / SetValue,因为这种方式更快。 但我真的不知道 Reflection.Emit 的内容是什么以及如何使用它来替代 GetValue 和 SetValue。有人能帮我解决这个问题吗?

I've been told to use Reflection.Emit instead of PropertyInfo.GetValue / SetValue because it is faster this way.
But I don't really know what stuff from Reflection.Emit and how to use it to substitute GetValue and SetValue. Can anybody help me with this ?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

淡莣 2024-08-19 18:10:18

只是一个替代答案;如果您想要性能,但需要类似的 API - 考虑 HyperDescriptor;这在下面使用了 Reflection.Emit (因此您不必这样做),但将其自身暴露在 PropertyDescriptor API 上,因此您只需使用:

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

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

Just an alternative answer; if you want the performance, but a similar API - consider HyperDescriptor; this uses Reflection.Emit underneath (so you don't have to), but exposes itself on the PropertyDescriptor API, so you can just use:

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

One line of code to enable it, and it handles all the caching etc.

不弃不离 2024-08-19 18:10:18

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

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

我有一篇博客文章如果您决定采用 CreateDelegate 路线,请了解更多详细信息。

If you're fetching/setting the same property many times, then using something to build a typesafe method will indeed be faster than reflection. However, I would suggest using Delegate.CreateDelegate instead of Reflection.Emit. It's easier to get right, and it's still blazingly fast.

I've used this in my Protocol Buffers implementation and it made a huge difference vs PropertyInfo.GetValue/SetValue. As others have said though, only do this after proving that the simplest way is too slow.

I have a blog post with more details if you decide to go down the CreateDelegate route.

泛滥成性 2024-08-19 18:10:18

使用 PropertyInfo.GetValue/SetValue

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

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

如果 - 并且真的只有 - 您绝对确定读/写值仍然是最糟糕的瓶颈,那么是时候开始了解在运行时生成 IL 的有趣世界了。

我真的怀疑这是否值得,每个级别都会增加代码的复杂性,而不是提高性能 - 仅在必要时才执行它们。

如果运行时对属性的访问是您的性能瓶颈,那么最好进行编译时访问(很难同时实现通用和超高性能)。

Use PropertyInfo.GetValue/SetValue

If you have performance problems cache the PropertyInfo object (don't repeatedly call GetProperty)

If - and only if - the use of reflection is the performance bottleneck of your app (as seen in a profiler) use Delegate.CreateDelegate

If - and really really only if - you are absolutely sure that reading/writing the values is still the worst bottleneck it's time to start learning about the fun world of generating IL in runtime.

I really doubt it's worth it, each of those levels increase the complexity of the code more then they improve performance - do them only if you have to.

And if runtime access to properties is your performance bottleneck it's probably better going for compile time access (it's hard time to be both generic and super high performance at the same time).

彩虹直至黑白 2024-08-19 18:10:18

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

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

The purpose of Reflection.Emit is completely different from that of PropertyInfo.Get/SetValue. Via Reflection.Emit, you can directly emit IL code, for example into dynamically compiled assemblies, and execute this code. Of course, this code could access your properties.

I seriously doubt that this will be much quicker then using PropertyInfo in the end, and it's not made for this purpose either. You could use Reflection.Emit as the code generator for a small compiler, for example.

小霸王臭丫头 2024-08-19 18:10:18

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

Using Reflection.Emit seems a little too "clever", as well as a premature optimization. If you profile your application, and you find that the GetValue/SetValue Reflection is the bottleneck, then you could consider optimizing, but probably not even then...

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文