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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/224232/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 18:52:20  来源:igfitidea点击:

What is the "cost" of .NET reflection?

c#.netoptimizationreflection

提问by Tom Anderson

Possible Duplicate:
How costly is .NET reflection?

可能的重复:
.NET 反射的成本是多少?

I am currently in a programming mentality that reflection is my best friend. I use it a lot for dynamic loading of content that allows "loose implementation" rather than strict interfaces, as well as a lot of custom attributes.

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

What is the "real" cost to using reflection?

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

Is it worth the effort for frequently reflected types to have cached reflection, such as our own pre-LINQ DAL object code on all the properties to table definitions?

频繁反射的类型是否值得缓存反射,例如我们自己的 pre-LINQ DAL 对象代码对表定义的所有属性?

Would the caching memory footprint outwieght the reflection CPU usage?

缓存内存占用会超过反射 CPU 使用吗?

采纳答案by smaclell

Reflection requires a large amount of the type metadata to be loaded and then processed. This can result in a larger memory overhead and slower execution. According to this articleproperty modification is about 2.5x-3x slower and method invocation is 3.5x-4x slower.

反射需要加载和处理大量类型元数据。这会导致更大的内存开销和更慢的执行。根据这篇文章,属性修改大约慢 2.5x-3x,方法调用慢 3.5x-4x。

Here is an excellent MSDN articleoutlining how to make reflection faster and where the overhead is. I highly recommend reading if you want to learn more.

这是一篇出色的MSDN 文章,概述了如何使反射更快以及开销在哪里。如果您想了解更多信息,我强烈建议您阅读。

There is also an element of complexity that reflection can add to the code that makes it substantially more confusing and hence difficult to work with. Some people, like Scott Hanselmanbelieve that by using reflection you often make more problems than you solve. This is especially the case if your teams is mostly junior devs.

还有一个复杂的元素,反射可以添加到代码中,使其更加混乱,因此难以使用。有些人,比如Scott Hanselman,相信通过使用反射,你经常会制造出比解决的更多的问题。如果您的团队主要是初级开发人员,则尤其如此。

You may be better off looking into the DLR (Dynamic Language Runtime) if you need alot of dynamic behaviour. With the new changes coming in .NET 4.0 you may want to see if you can incorporate some of it into your solution. The added support for dynamic from VB and C# make using dynamic code very elegant and creating your own dynamic objects fairly straight forward.

如果您需要大量动态行为,最好查看 DLR(动态语言运行时)。随着 .NET 4.0 中的新变化,您可能想看看是否可以将其中的一些融入到您的解决方案中。VB 和 C# 对动态的额外支持使得使用动态代码非常优雅,并且可以相当直接地创建您自己的动态对象。

Good luck.

祝你好运。

EDIT: I did some more poking around Scott's site and found this podcaston reflection. I have not listened to it but it might be worth while.

编辑:我在 Scott 的网站上做了更多的探索,并在反思中发现了这个播客。我没有听过它,但它可能值得。

回答by Llyle

With great power comes great responsibility.

拥有权利的同时也被赋予了重大的责任。

As you say, reflection has costs associated with it, and depending on how much reflection you do it can slow the application down significantly.

正如您所说,反射具有与之相关的成本,并且取决于您进行多少反射,它会显着降低应用程序的速度。

One of the very approrpiate places to use it is for IoC (Inversion of Control) since, depending on the size of your application, would probably have more benefits than not.

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

回答by Tom Anderson

Thanks for the great links and great comments, especially on the part of the Jr Devs, that hit it right on the money.

感谢伟大的链接和伟大的评论,尤其是在 Jr Devs 方面,这对金钱来说是正确的。

For us it is easier for our junior developers to do this:

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

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

rather than some larger impelementations of DAL. This speeds up their building of the DAL objects, while hiding all the internal workings for the senior developers to gut out.

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

Too bad LINQ didn't come out earlier, I feel at times we wrote half of it.

可惜LINQ没有早点出来,我觉得有时候我们写了一半。

回答by Marc Gravell

There are lots of things you can do to speed up reflection. For example, if you are doing lots of property-access, then HyperDescriptormight be useful.

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

If you are doing a lot of method-invoke, then you can cache methods to typed delegates using Delegate.CreateDelegate- this then does the type-checking etc only once (during CreateDelegate).

如果您正在执行大量方法调用,那么您可以使用将方法缓存到类型化委托中Delegate.CreateDelegate- 然后只进行一次类型检查等(在 期间CreateDelegate)。

If you are doing a lot of object construction, then Delegate.CreateDelegatewon't help (you can't use it on a constructor) - but (in 3.5) Expressioncan be used to do this, again compiling to a typed delegate.

如果您正在进行大量对象构造,那么Delegate.CreateDelegate将无济于事(您不能在构造函数上使用它)-但是(在 3.5 中)Expression可用于执行此操作,再次编译为类型化委托。

So yes: reflection is slow, but you can optimize it without too much pain.

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

回答by jonnii

One thing that can sometimes bite you when using reflection is not updating calls using reflection when doing refactoring. Tools like resharper will prompt you to update comments and strings when you change a method name, so you can catch most of them that way, but when you're calling methods that have been dynamically generated or the method name has been dynamically generated you might miss something.

使用反射时有时会咬你的一件事是在重构时不使用反射更新调用。像 resharper 这样的工具会在您更改方法名称时提示您更新注释和字符串,因此您可以通过这种方式捕获大部分内容,但是当您调用动态生成的方法或动态生成的方法名称时,您可能会想念一些东西。

The only solution is good documentation and thorough unit testing.

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