反射真的很慢吗?

发布于 2024-12-27 06:51:38 字数 207 浏览 2 评论 0原文

人们普遍认为反思是缓慢的,因此应尽可能避免反思。但在目前的情况下,这种信念是真的吗?当前 .net 版本中发生了很多变化,例如使用 IL Weaving(即 IL Emit)等,而不是执行反射的传统 PropertyInfo 和 MethodInfo 方式。

这是任何令人信服的证据,证明新的反射不再那么慢并且可以使用。有没有更好的方法来读取属性数据?

谢谢, 巴斯卡

This is a common belief that reflection is slow and try to avoid it as much as possible. But is that belief true, in the current situation? There has been lot of changes in the current .net versions like, use of IL Weaving (i.e. IL Emit) etc, as opposed to traditional PropertyInfo and MethodInfo ways of performing reflection.

Is that any convincing proof, that the new reflection is not that slow any more, and can be used. Is there better way to read attribute data?

Thanks,
Bhaskar

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

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

发布评论

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

评论(7

压抑⊿情绪 2025-01-03 06:51:38

仔细想想,反射的速度真是令人印象深刻。

可以以与任何其他委托相当的速度调用来自 ConstructorInfoMethodInfo 的缓存委托。

ILGenerator.Emit 创建的委托(顺便说一句,这并不是什么新鲜事,它从版本 1 开始就出现在 .NET 中)同样可以同样快速地调用。

通过发出或调用 ConstructorInfo 的委托获得的对象将与任何其他对象一样快。

如果您通过动态加载程序集、使用反射查找要调用的方法并调用它来获取对象,并且它实现了一个已定义的接口,您可以通过该接口从该点开始调用它,那么它的速度将同样快它被用作该接口的另一个实现。

总而言之,反射为我们提供了做事的方法,如果没有反射,我们(如果我们能做到的话)就必须使用编码和执行速度都较慢的技术。

它还为我们提供了比其他方法更复杂、更脆弱、类型安全性较差且性能较差的方法。几乎每一行 C# 代码都可以替换为一大块使用反射的代码。这段代码几乎肯定会在很多方面比原始代码更糟糕,而性能是其中最不重要的。

很可能“避免反思,因为它很慢”的建议源于这样一种信念,即那种仅仅因为新技术看起来很酷就会为任何新技术而疯狂的开发人员更有可能被“它将是”所警告。慢”比“它会不太惯用,更容易出错并且更难维护”。这种信念很可能是完全正确的。

但在大多数情况下,当最自然、最明显的方法是使用反射时,它的性能也不会比避免反射的真正复杂的尝试低。

如果性能问题适用于反射中的任何内容,那么它实际上适用于隐藏的用途:

在只需少量工作就可以避免它的情况下,使用动态似乎是明智的。这里性能差异可能值得考虑。

在 ASP.NET 中,使用 <%#DataBinder.Eval(Container.DataItem, "SomeProperty")%> 更容易,但通常性能低于 <#((SomeType)Container .DataItem).SomeProperty%><%#SomeCodeBehindProvidedCallWithTheSameResult%>。 90% 的时间我仍然会使用前者,只有当我真正关心给定页面的性能或更可能的情况下才使用后者,因为对同一个对象执行许多操作实际上会使后者更自然。

因此,总而言之,计算机中的一切仍然是“慢”的,而它们受到在单个宇宙中以消耗能量和花费时间的方式工作的要求的限制,以达到某种“慢”值。不同的反射技术有不同的成本,但替代方案也是如此。在明显的方法的情况下,不要过多地注意反射,而要注意隐藏的反射,在这种情况下,另一种不太明显的方法可能会很好用。

当然,无论您使用什么技术,都要明智地编码。如果您要连续调用同一个委托一百次,那么您应该存储它而不是每次调用都获取它,并且无论获取它的方式是否通过反射,这都会发生。

When you think about it, reflection is pretty darn impressive in how fast it is.

A cached delegate from a ConstructorInfo or MethodInfo can be called with speed comparable to any other delegate.

A delegate created from ILGenerator.Emit (which incidentally isn't new, it's been in .NET since version 1) can likewise be called just as fast.

An object obtained through emitting or calling a ConstructorInfo's delegate will be just as fast as any other object.

If you obtain an object by loading an assembly dynamically, using reflection to find the method to call, and calling it, and it implements a defined interface through which you call it from that point on, then it'll be just as fast in how it's used as another implementation of that interface.

In all, reflection gives us ways of doing things that without it we would - if we could do them at all - have to use techniques that are slower both to code and to execute.

It also gives us means of doing things that are more complicated, more brittle, less type-safe and less performant than other means too. Pretty much every line of C# code can be replaced by a big chunk of code that uses reflection. This code will almost certainly be worse than the original line in a whole bunch of ways, and performance is the least of them.

Quite possibly the "avoid reflection because its slow" advice stems from the belief that the sort of developer that would go nuts for any new technique just because it seemed cool would be the sort that would be more likely warned off by "it'll be slower" than by "it'll be less idiomatic, more error-prone and harder to maintain". Quite possibly this belief is completely correct.

For the most part though, when the most natural and obvious approach is to use reflection, then it also won't be less performant than a really convoluted attempt to avoid it.

If performance concerns apply to anything in reflection, its really to the uses that are hidden:

Using dynamic can seem sensible in a case where only a little work could avoid it. Here the performance difference may be worth considering.

In ASP.NET, using <%#DataBinder.Eval(Container.DataItem, "SomeProperty")%> is easier but generally less performant than <#((SomeType)Container.DataItem).SomeProperty%> or <%#SomeCodeBehindProvidedCallWithTheSameResult%>. I'll still use the former 90% of the time, and the latter only if I really care about a given page's performance or more likely because doing many operations on the same object makes the latter actually more natural.

So in all, everything remains "slow" in computers while they are bounded by the requirement to work in a single universe in a way that consumes energy and takes time, for some value of "slow". Different reflection techniques have different costs, but so does the alternatives. Beware not so much of reflection in cases where it's the obvious approach as hidden reflection where another approach just slightly less obvious may serve well.

And of course, code wisely with whatever technique you use. If you're going to call the same delegate a hundred times in a row, you should be storing it rather than obtaining it each call, and that would go whether the way to obtain it was through reflection or not.

街角迷惘 2025-01-03 06:51:38

这一切都取决于。
是的,使用反射毫无疑问比不使用反射慢,但是您必须着眼于大局:

例如,想象您的代码执行一些反射,然后通过网络从数据库加载一些数据。
在这种情况下,您可以完全忽略反射的额外成本,因为通过网络的数据库请求可能会花费更长的时间。

It all depends.
Yes, using reflection is without any doubt slower than not using reflection, but you have to look at the big picture:

For example, imagine that your code does some reflection and then loads some data from a database over the network.
In this case, you can completely neglect the additional cost for reflection because the database request over the network will likely take much, much longer.

拥抱我好吗 2025-01-03 06:51:38

我不会担心性能成本那么多。并不是说性能并不重要,但在很多情况下,一两毫秒并不明显,也不值得选择更复杂的编码替代方案。看看

我通常更喜欢这种方法:

  1. 如果需要,编写简单的代码
  2. 来衡量性能
  3. ,优化最大的打击者

I wouldn't worry about the performance cost that much. Not saying performance doesn't matter, but in a lot of cases, a millisecond or two isn't noticeable or worth choosing a more complicated coding alternative. Take a look here.

I generally prefer this approach:

  1. write simple code
  2. measure performance
  3. optimize the biggest hitter, if needed
情绪操控生活 2025-01-03 06:51:38

您提到共同信念是什么意思?反射不是一个实心块。您应该分开考虑每种方法。例如,通过默认构造函数创建对象比简单调用慢几倍,而创建参数构造函数则慢数十倍。所以如果你想研究速度,就做一个基准测试,对你需要的具体功能进行基准测试。

附言。使用 C#,您始终可以即时创建和编译表达式,如果你设法做到这一点会比反思快得多。

Whad do you mean by mentioning a common belief? Reflection is not a solid block. You should consider each method apart. For instance, creating an object through a default constructor is few times slower than a simple call, whilst creating a parametered constructor is tens time slower. So if you want to study the speed, do a benchmark and benchmark the concrete functions you need.

PS. Using C#, you can always create and compile expressions on the fly which if you manage to do it would be much faster than reflection.

情痴 2025-01-03 06:51:38

是的,当我们尝试进行大量操作或循环操作时,反射很慢。
您也可以尝试动态选项。使用动态选项,它可以被缓存,并且最终会比反射更快。

yes reflection is slow when we try to do on bulky opertations or with in a loop.
you can try out dynamic options as well . with dynamic option its can be cached and eventually will be faster than reflection.

捂风挽笑 2025-01-03 06:51:38

如果您需要查看应用于源代码的属性,那么您几乎必须使用反射。

有些反射操作很快,例如Object.GetType(),但有些操作相对较慢,例如Type.FindMethod("MyMethod")。

一般来说,我想说,如果您的应用程序偶尔使用反射,则不应该有性能问题。另一方面,如果您的应用程序广泛使用反射,那么您可能会发现速度有些缓慢。

If you need to look at attributes applied to source code, then you pretty much have to use reflection.

Some reflection operations are fast, such as Object.GetType(), but some operations are relatively slow, such as Type.FindMethod("MyMethod").

In general, I would say that if your application makes occasional use of Reflection, there should be no performance concern. On the other hand, if your application uses Reflection extensively, then you might observe some slowness.

耳根太软 2025-01-03 06:51:38

反省是一项繁重的工作。说慢是相对于很多事情来说的。通过反射调用方法/构造函数很慢,但使用反射仅检索元数据则不然。

请记住,反射必须仅用于检索元数据。
如果您需要调用方法、运行某些东西,只需在初始化时发出动态类型/方法并通过接口/委托调用它们。

Introspection is an heavy job. Saying slow is relative to a lot of things. Invoking method/constructor through reflection is slow, but using reflection to only retreive metadatas is not.

Keep in mind, reflection must be only use to retrieve metadatas.
If you need to invoke method, running something, just emit dynamic types/methods at initialization time and invoke them through interfaces/delegates.

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