.NET反射的“成本”是多少?

时间:2008-10-22 02:10:51

标签: c# .net optimization reflection

  

可能重复:
  How costly is .NET reflection?

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

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

经常反映的类型是否值得缓存反射,例如我们自己的LINQ DAL目标代码在表定义的所有属性上?

缓存内存占用量是否会超过反射CPU使用率?

5 个答案:

答案 0 :(得分:56)

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

这是一个很好的this article概述如何使反射更快以及开销在哪里。如果您想了解更多信息,我强烈建议您阅读。

还有一个复杂的元素,反射可以添加到代码中,使其更加混乱,因此难以使用。有些人,比如MSDN article认为,通过使用反射,你经常会遇到比你解决的问题更多的问题。如果您的团队主要是初级开发人员,情况尤其如此。

如果您需要很多动态行为,可能最好不要查看DLR(动态语言运行时)。随着.NET 4.0中的新变化,您可能希望了解是否可以将其中的一部分合并到您的解决方案中。 VB和C#增加了对动态的支持,使得动态代码非常优雅,并且可以非常直接地创建自己的动态对象。

祝你好运。

编辑:我在斯科特的网站上做了一些更多的讨论,发现这个Scott Hanselman正在反思。我没有听过,但可能值得一试。

答案 1 :(得分:17)

你可以做很多事情来加速反思。例如,如果您正在进行大量的属性访问,那么HyperDescriptor可能会有用。

如果你正在进行大量的方法调用,那么你可以使用Delegate.CreateDelegate将方法缓存到键入的代理 - 然后只进行一次类型检查(在CreateDelegate期间)。

如果你正在进行大量的对象构建,那么Delegate.CreateDelegate将无济于事(你不能在构造函数上使用它) - 但是(在3.5中)Expression可以用来做这个,再次编译成一个打字的代表。

所以是的:反射很慢,但你可以在没有太多痛苦的情况下进行优化。

答案 2 :(得分:2)

强大的力量带来了巨大的责任。

正如你所说,反射有与之相关的成本,并且取决于你做多少反射,它可以显着减慢应用程序。

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

答案 3 :(得分:2)

感谢优秀的链接和精彩的评论,特别是Jr Devs的评论,这些都是在钱上做的。

对我们来说,我们的初级开发人员更容易这样做:

[TableName("Table")]
public class SomeDal : BaseDal
{
    [FieldName("Field")]
    public string Field
}
而不是DAL的一些更大的要求。这加快了他们构建DAL对象的速度,同时隐藏了高级开发人员的所有内部工作方式。

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

答案 4 :(得分:0)

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

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