2008-10-22 50 views
64

可能重复:
How costly is .NET reflection?什么是.NET反射的“成本”?

目前我在编程的心态,反思是我最好的朋友。我用它来动态加载内容,允许“松散实现”而不是严格的接口,以及许多自定义属性。

使用反射的“真实”成本是多少?

对于频繁反映的类型来说,是否值得让缓存反射,比如我们自己的所有属性中的LINQ DAL目标代码到表定义?

高速缓存的内存占用会超出反射CPU使用率吗?

+20

我在世界上是如何得到一个3个月大的回答的话题的投票? – 2009-01-16 20:33:01

+0

我们使用泛型基类和反射来自动化我们的数据访问层。我们的大多数泛型基类都是使用反射来实现的。这极大地减少了我们为重复性任务编写的代码行数量。但是出现了性能问题。你采用了哪种解决方案? – 2009-06-30 06:59:57

+0

我们采用了非常类似的方法,现在正在缓存元数据。 – 2009-06-30 07:23:43

回答

53

反射需要加载大量的类型元数据,然后进行处理。这可能导致更大的内存开销和更慢的执行。根据this article属性修改约慢2.5x-3x,方法调用速度降低3.5x-4x。

下面是一个很好的MSDN article概述了如何更快地进行反射和开销。如果你想了解更多信息,我强烈建议阅读。

反射可能会增加代码的复杂性,这使得代码变得非常复杂,因此很难处理。有些人,如Scott Hanselman认为,通过反思,你经常会遇到比解决问题更多的问题。如果您的团队主要是初级开发人员,情况尤其如此。

如果您需要大量的动态行为,您最好查看DLR(动态语言运行时)。随着.NET 4.0中出现新的变化,您可能需要了解是否可以将其中的一些内容纳入到您的解决方案中。从VB和C#中动态添加的支持使得使用动态代码非常优雅,并且非常简单地创建自己的动态对象。

祝你好运。

编辑:我做了一些更多的斯科特的网站戳,发现这个podcast反思。我没有听过,但它可能是值得的。

2

随着巨大的权力来承担巨大的责任。

正如您所说,反射会产生相关成本,并且取决于您做了多少反射,可能会显着减慢应用程序的速度。

其中一个非常适合使用它的地方是IoC(控制反转),因为根据应用程序的大小,可能会有更多的好处。

1

非常感谢您的宝贵意见和建议,特别是Jr Devs的部分,这一点非常重要。

对我们来说是更容易为我们的初级开发人员要做到这一点:

[TableName("Table")] 
public class SomeDal : BaseDal 
{ 
    [FieldName("Field")] 
    public string Field 
} 

而不是DAL的一些较大impelementations。这加快了他们构建DAL对象的速度,同时隐藏了高级开发人员所需的所有内部工作。

太糟糕了LINQ没有早点出来,我觉得有时我们写了一半。

15

有很多事情可以加快思考速度。例如,如果您正在进行大量财产访问,那么HyperDescriptor可能会有用。

如果您正在执行很多方法调用,那么您可以使用Delegate.CreateDelegate缓存方法以键入代理 - 然后仅进行一次类型检查(在CreateDelegate期间)。

如果你正在做很多的对象构造,那么Delegate.CreateDelegate将不会帮助(你不能在构造函数中使用它) - 但是(在3.5)Expression可以用来做到这一点,再次编译为一个类型代表。

所以是的:反射是缓慢的,但你可以优化它,而不会太痛苦。

0

使用反射时有时会咬你的一件事是在重构时不使用反射更新调用。像resharper这样的工具会提示你在更改方法名称时更新注释和字符串,这样你就可以以这种方式捕获大部分的方法,但是当你调用动态生成的方法或者动态生成方法名称时,你可能会错过了什么。

唯一的解决方案是良好的文档和彻底的单元测试。