为什么反射在.NET中表现不佳?

Mal*_*olm 5 .net reflection performance

我有兴趣知道技术原因:为什么反射在.NET中表现不佳?

Rex*_*x M 16

反射效果不佳

这是一个非常负载的声明."表现良好"是相对的.与静态代码相比,反射调用的表现不尽相同.但是,几乎在所有情况下,.NET中的反射都非常快.我不能低估这一点.反思在.NET 1.x天以及其他语言中得到了不好的声誉,但.NET 2.0+中的反映速度非常.

在99%的案例中,"反思太慢"是一个无关紧要的问题.我怀疑你是否需要费心去测量反射呼叫与静态呼叫的性能影响.


jri*_*sta 5

简单地说"反射"表现得很慢就是在很宽的毯子下面堆积了很多功能..NET中的反思有几个类,每个类都有不同级别的"性能".首先,typeof()运算符的使用实际上是一种反射形式......它查询CLR元数据的类型.但是,typeof()执行速度非常快(在接近空闲时间.)使用其他类型相关的"反射",例如is运算符,sizeof()运算符等也几乎是免费的(它们基本上就像它们是静态代码一样.)

typeof()考虑到指针遍历和元数据探测的数量,用于检索有关类型的信息的反射虽然慢于,但也非常非常快.元数据探测是.NET代码的一种常见做法,特别是在处理自定义属性时.

关于反思的重要性能问题与调用有关.访问类型信息和阅读元数据非常轻松.在涉及动态调用属性,索引器,方法或通过反射动态构造新类型的那一刻,您将获得数量级的性能影响.

但是,反射仍然是进程内执行,因此在您担心稍微动态调用的性能损失之前,请确保没有任何明显更大的性能瓶颈,例如进程间执行,网络调用(即数据库) ,网络服务等.当谈到性能时,从最大的性能打击开始,然后从那里开始工作.从性能角度来看,反射(包括动态调用)通常是您应该担心的最后一件事.

附录:

稍后想一想,但如果您需要对后期绑定类型成员进行高度动态调用,则应该考虑轻量级代码生成.使用System.Reflection.Emit命名空间,您可以使用DynamicMethod等实用程序在运行时生成可执行早期绑定调用的轻量级代码.缓存此生成的代码可降低生成代码的初始成本,从而使您可以获得具有早期性能的后期绑定调用的好处.


Jul*_*anR 2

反射表现良好,它只是比静态代码多做很多事情。

假设您有以下代码片段:

typeof(SomeClass).GetMethod("SomeStaticMethod").
Invoke(null, new object[] { 1, 2, 3 });
Run Code Online (Sandbox Code Playgroud)

这和这个是一样的:

SomeClass.SomeStaticMethod(1, 2, 3);
Run Code Online (Sandbox Code Playgroud)

但显然第一个任务还有很多工作要做。它必须获取类型信息,遍历它以查看是否有 SomeStaticMethod 方法,检查它是什么类型,在实例上调用该方法,如果它是静态的,则不调用该方法,并传递对象数组作为参数,对整数进行装箱/拆箱在这种情况下也是如此。

这可能是一个非常广泛的总结,毫无疑问还有更多的事情发生。然而尽管如此,反射仍然非常快,并在很多领域使用,从 WinForms 上的数据绑定到 ASP.NET MVC 中的模型绑定(您对此站点发出的每个请求,基于 MVC 构建,都涉及一大堆反射,但,网站速度非常快,MVC 被认为是一个非常快的框架)。