C#泛型有性能优势吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/116988/
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
Do C# Generics Have a Performance Benefit?
提问by Roberto Bonini
I have a number of data classes representing various entities.
我有许多代表各种实体的数据类。
Which is better: writing a generic class (say, to print or output XML) using generics and interfaces, or writing a separate class to deal with each data class?
哪个更好:使用泛型和接口编写泛型类(例如,打印或输出 XML),还是编写单独的类来处理每个数据类?
Is there a performance benefit or any other benefit (other than it saving me the time of writing separate classes)?
是否有性能优势或任何其他优势(除了节省我编写单独类的时间)?
采纳答案by Danimal
There's a significant performance benefit to using generics -- you do away with boxing and unboxing. Compared with developing your own classes, it's a coin toss (with one side of the coin weighted more than the other). Roll your own only if you think you can out-perform the authors of the framework.
使用泛型有显着的性能优势——您无需装箱和拆箱。与开发自己的类相比,这是抛硬币(硬币的一面比另一面更重)。仅当您认为自己可以胜过框架的作者时才推出自己的产品。
回答by torial
I did some simple benchmarking on ArrayList's vs Generic Lists for a different question: Generics vs. Array Lists, your mileage will vary, but the Generic List was 4.7 times faster than the ArrayList.
对于另一个问题,我对 ArrayList 与 Generic Lists 做了一些简单的基准测试:Generics vs. Array Lists,你的里程会有所不同,但 Generic List 比 ArrayList 快 4.7 倍。
So yes, boxing / unboxing are critical ifyou are doing a lot of operations. If you are doing simple CRUD stuff, I wouldn't worry about it.
所以是的,如果您要进行大量操作,装箱/拆箱至关重要。如果你正在做简单的 CRUD 东西,我不会担心。
回答by Nir
if you compare a generic list (for example) to a specific list for exactly the type you use then the difference is minimal, the results from the JIT compiler are almost the same.
如果您将通用列表(例如)与您使用的类型的特定列表进行比较,则差异很小,JIT 编译器的结果几乎相同。
if you compare a generic list to a list of objects then there is significant benefits to the generic list - no boxing/unboxing for value types and no type checks for reference types.
如果将泛型列表与对象列表进行比较,那么泛型列表有显着的好处 - 没有对值类型进行装箱/拆箱,也没有对引用类型进行类型检查。
also the generic collection classes in the .net library were heavily optimized and you are unlikely to do better yourself.
.net 库中的泛型集合类也进行了大量优化,您自己也不太可能做得更好。
回答by Khoth
If you're thinking of a generic class that calls methods on some interface to do its work, that will be slower than specific classes using known types, because calling an interface method is slower than a (non-virtual) function call.
如果您正在考虑调用某个接口上的方法来完成其工作的泛型类,这将比使用已知类型的特定类慢,因为调用接口方法比(非虚拟)函数调用慢。
Of course, unless the code is the slow part of a performance-critical process, you should focus of clarity.
当然,除非代码是性能关键过程的缓慢部分,否则您应该关注清晰性。
回答by Hristo Deshev
Generics are one of the way to parameterize code and avoid repetition. Looking at your program description and your thought of writing a separate class to deal with each and every data object, I would lean to generics. Having a single class taking care of many data objects, instead of many classes that do the same thing, increases your performance. And of course your performance, measured in the ability to change your code, is usually more important than the computer performance. :-)
泛型是参数化代码和避免重复的方法之一。看看你的程序描述和你写一个单独的类来处理每个数据对象的想法,我倾向于泛型。使用一个类来处理多个数据对象,而不是多个执行相同操作的类,可以提高您的性能。当然,以更改代码的能力来衡量的性能通常比计算机性能更重要。:-)
回答by Andrew Queisser
Generics in C# are truly generic types from the CLR perspective. There should not be any fundamental difference between the performance of a generic class and a specific class that does the exact same thing. This is different from Java Generics, which are more of an automated type cast where needed or C++ templates that expand at compile time.
从 CLR 的角度来看,C# 中的泛型是真正的泛型类型。泛型类的性能与执行完全相同的特定类的性能之间不应该有任何根本区别。这与 Java 泛型不同,后者更像是在需要的地方进行自动类型转换或在编译时扩展的 C++ 模板。
Here's a good paper, somewhat old, that explains the basic design: "Design and Implementation of Generics for the .NET Common Language Runtime".
这是一篇很好的论文,有点旧,它解释了基本设计: “. NET 公共语言运行时泛型的设计和实现”。
If you hand-write classes for specific tasks chances are you can optimize some aspects where you would need additional detours through an interface of a generic type.
如果您为特定任务手写类,那么您可以优化某些方面,在这些方面您需要通过通用类型的接口进行额外的绕道。
In summary, there may be a performance benefit but I would recommend the generic solution first, then optimize if needed. This is especially true if you expect to instantiate the generic with many different types.
总之,可能会有性能优势,但我会先推荐通用解决方案,然后根据需要进行优化。如果您希望使用许多不同类型实例化泛型,则尤其如此。
回答by JohnIdol
According to Microsoft, Generics are faster than casting (boxing/unboxing primitives) which is true. They also claim generics provide better performance than casting between reference types, which seems to be untrue(no one can quite prove it).
根据微软的说法,泛型比转换(装箱/拆箱原语)更快,这是真的。他们还声称泛型比引用类型之间的转换提供了更好的性能,这似乎是不真实的(没有人能完全证明这一点)。
Tony Northrup - co-author of MCTS 70-536: Application Development Foundation - states in the same book the following:
Tony Northrup - MCTS 70-536: Application Development Foundation 的合著者 - 在同一本书中声明如下:
I haven't been able to reproduce the performance benefits of generics; however, according to Microsoft, generics are faster than using casting. In practice, casting proved to be several times faster than using a generic. However, you probably won't notice performance differences in your applications. (My tests over 100,000 iterations took only a few seconds.) So you should still use generics because they are type-safe.
我无法重现泛型的性能优势;然而,根据微软的说法,泛型比使用强制转换更快。在实践中,铸造证明比使用泛型要快几倍。但是,您可能不会注意到应用程序中的性能差异。(我超过 100,000 次迭代的测试只用了几秒钟。)所以你仍然应该使用泛型,因为它们是类型安全的。
I haven't been able to reproduce such performance benefits with generics compared to casting between reference types - so I'd say the performance gain is "supposed" more than "significant".
与引用类型之间的转换相比,我无法通过泛型重现这种性能优势 - 所以我会说性能增益“应该”比“显着”更重要。
回答by Jason Hymanson
In the case of generic collections vs. boxing et al, with older collections like ArrayList, generics are a performance win. But in the vast majority of cases this is not the most important benefit of generics. I think there are two things that are of much greater benefit:
在泛型集合与拳击等人的情况下,对于像 ArrayList 这样的旧集合,泛型是性能上的胜利。但在绝大多数情况下,这并不是泛型最重要的好处。我认为有两件事有更大的好处:
- Type safety.
- Self documenting aka more readable.
- 类型安全。
- 自我记录又名更具可读性。
Generics promote type safety, forcing a more homogeneous collection. Imagine stumbling across a string when you expect an int. Ouch.
泛型促进类型安全,迫使集合更加均匀。想象一下,当您期望一个 int 时,会绊倒一个字符串。哎哟。
Generic collections are also more self documenting. Consider the two collections below:
通用集合也更具有自我记录性。考虑以下两个集合:
ArrayList listOfNames = new ArrayList();
List<NameType> listOfNames = new List<NameType>();
Reading the first line you might think listOfNames is a list of strings. Wrong! It is actually storing objects of type NameType. The second example not only enforces that the type must be NameType (or a descendant), but the code is more readable. I know right away that I need to go find TypeName and learn how to use it just by looking at the code.
阅读第一行,您可能认为 listOfNames 是一个字符串列表。错误的!它实际上存储的是 NameType 类型的对象。第二个示例不仅强制类型必须是 NameType(或后代),而且代码更具可读性。我马上就知道我需要去查找 TypeName 并通过查看代码来学习如何使用它。
I have seen a lot of these "does x perform better than y" questions on StackOverflow. The question here was very fair, and as it turns out generics are a win any way you skin the cat. But at the end of the day the point is to provide the user with something useful. Sure your application needs to be able to perform, but it also needs to not crash, and you need to be able to quickly respond to bugs and feature requests. I think you can see how these last two points tie in with the type safety and code readability of generic collections. If it were the opposite case, if ArrayList outperformed List<>, I would probably still take the List<> implementation unless the performance difference was significant.
我在 StackOverflow 上看到了很多这样的“x 是否比 y 表现更好”的问题。这里的问题非常公平,而且事实证明,无论您如何剥猫皮,泛型都是一种胜利。但归根结底,重点是为用户提供一些有用的东西。当然,您的应用程序需要能够执行,但也需要不会崩溃,并且您需要能够快速响应错误和功能请求。我想你可以看到最后两点是如何与泛型集合的类型安全和代码可读性联系起来的。如果是相反的情况,如果 ArrayList 的性能优于 List<>,除非性能差异很大,否则我可能仍会采用 List<> 实现。
As far as performance goes (in general), I would be willing to bet that you will find the majority of your performance bottlenecks in these areas over the course of your career:
就性能而言(一般而言),我敢打赌,在您的职业生涯中,您会发现以下领域的大部分性能瓶颈:
- Poor design of database or database queries (including indexing, etc),
- Poor memory management (forgetting to call dispose, deep stacks, holding onto objects too long, etc),
- Improper thread management (too many threads, not calling IO on a background thread in desktop apps, etc),
- Poor IO design.
- 数据库或数据库查询(包括索引等)设计不佳,
- 糟糕的内存管理(忘记调用 dispose、深堆栈、持有对象太久等),
- 线程管理不当(线程过多,不在桌面应用程序的后台线程上调用 IO 等),
- 糟糕的 IO 设计。
None of these are fixed with single-line solutions. We as programmers, engineers and geeks want to know all the cool little performance tricks. But it is important that we keep our eyes on the ball. I believe focusing on good design and programming practices in the four areas I mentioned above will further that cause far more than worrying about small performance gains.
这些都不是用单线解决方案解决的。作为程序员、工程师和极客,我们想知道所有很酷的性能小技巧。但重要的是我们要关注球。我相信在我上面提到的四个领域专注于良好的设计和编程实践将进一步导致不仅仅是担心小的性能提升。
回答by Jason Short
Not only yes, but HECK YES. I didn't believe how big of a difference they could make. We did testing in VistaDB after a rewrite of a small percentage of core code that used ArrayLists and HashTables over to generics. 250% or more was the speed improvement.
不仅是,而且是的。我不相信他们能产生多大的不同。在将一小部分使用 ArrayLists 和 HashTables 的核心代码重写为泛型之后,我们在 VistaDB 中进行了测试。250% 或更多是速度的提高。
Read my blog about the testingwe did on generics vs weak type collections. The results blew our mind.
阅读我的博客,了解我们对泛型与弱类型集合所做的测试。结果让我们大吃一惊。
I have started rewriting lots of old code that used the weakly typed collections into strongly typed ones. One of my biggest grips with the ADO.NET interface is that they don't expose more strongly typed ways of getting data in and out. The casting time from an object and back is an absolute killer in high volume applications.
我已经开始将许多使用弱类型集合的旧代码重写为强类型集合。我对 ADO.NET 接口的最大把握之一是它们没有公开更强类型的数据输入和输出方式。在大批量应用中,从对象到返回的投射时间是绝对的杀手。
Another side effect of strongly typing is that you often will find weakly typed reference problems in your code. We found that through implementing structsin some cases to avoid putting pressure on the GC we could further speed up our code. Combine this with strongly typing for your best speed increase.
强类型的另一个副作用是您经常会在代码中发现弱类型引用问题。我们发现通过在某些情况下实现结构体来避免对 GC 施加压力,我们可以进一步加速我们的代码。将此与强输入相结合,以获得最佳速度提升。
Sometimes you have to use weakly typed interfaces within the dot net runtime. Whenever possible though look for ways to stay strongly typed. It really does make a huge difference in performance for non trivial applications.
有时您必须在 dot net 运行时中使用弱类型接口。只要有可能,就会寻找保持强类型的方法。它确实对非平凡应用程序的性能产生了巨大的影响。
回答by John Gardner
See Rico Mariani's Blog at MSDN too:
也可以在 MSDN 上查看 Rico Mariani 的博客:
http://blogs.msdn.com/ricom/archive/2005/08/26/456879.aspx
http://blogs.msdn.com/ricom/archive/2005/08/26/456879.aspx
Q1: Which is faster?
The Generics version is considerably faster, see below.
Q1:哪个更快?
泛型版本要快得多,见下文。
The article is a little old, but gives the details.
文章有点旧,但提供了详细信息。