规范化 .net 泛型

发布于 2024-08-07 02:05:57 字数 62 浏览 6 评论 0原文

在重写程序集时,如果我指示编译器为每个泛型实例生成非泛型类型,应用程序的代码会变得更大,但仍具有相同的性能吗?

While rewriting an assembly if I were to instruct a compiler to generate a nongeneric type for each generic instance would the application just get bigger in code and yet have the same performance?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

烟雨扶苏 2024-08-14 02:05:57

修改编译代码的大小(无论是 JIT 前还是 JIT 后)都会对性能产生影响。

例如,增加可执行代码的数量可能会导致额外的缓存未命中,或耗尽更多的虚拟内存。这两种情况都会减慢程序的执行速度。

此外,增加程序集中存在的命名类型的数量可能会减慢运行时间。如果运行时必须检查较大的数据结构来解析类型名称,则解析类型名称和执行 JIT 编译可能需要更长时间。

最后,如果 JIT 的类型较多,那么 CLR 最终可能会花费更多的时间来生成代码。

您需要进行测试才能确定,但​​我的猜测是,执行您所说的操作会产生净负面影响。

不过,CLR 对于它生成的通用代码非常聪明。泛型方法的不同引用类型实例最终会使用大部分相同的本机方法体,除了需要加载类型标记的部分。然而,值类型实例最终会获得自己独特的本机方法体。

这通常可以提供良好的性能。它平衡了代码膨胀对性能的影响和额外装箱对性能的影响。

当然,您构建的工作负载的 CLR 设计可能会导致非最佳性能。然而,这些案例对我来说似乎相当病态。我敢打赌,对于大多数实际代码,直接使用 CLR 泛型会获得更好的性能。

Modifying the size of the compiled code, either pre or post JIT, can have an impact on performance.

For example, increasing the amount of executable code can cause extra cache misses, or use up more Virtual Memory. Both of those cases can slowdown execution of the program.

Also, increasing the number of named types present in an assembly can slow down the runtime. If the runtime has to examine larger data structures to resolve type names, then resolving type names and performing JIT compilation can take longer.

Finally, if their are more types to JIT, then the CLR can end up spending a larger fraction of its time generating code.

You would need to run tests to be sure, but my guess is that doing what you are talking about would have a net-negative effect.

The CLR is pretty smart about the generic code that it generates, though. Different reference type instatiations of generic methods end up using most of the same native method body, except for the parts that require loading type tokens. Value type instatiations, however, end up getting their own unique native method bodies.

This generally provides good performance. It balances the performance impact of code bloat against the performance impact of extra boxing.

It certainly is possible for you to construct workloads where the CLR design would lead to non-optimal performance. Those cases, however, seem pretty pathological to me. I'm willing to bet that with most real code, you would get better perf by just using CLR generics directly.

好听的两个字的网名 2024-08-14 02:05:57

不,代码和性能实际上是相同的。

编译器已经生成了特定的类。我不确定语言编译器完成了多少工作,JIT 编译器完成了多少工作,但最终结果实际上是相同的。

No, the code and performance would be practically the same.

The compiler already generates the specific classes already. I'm not sure how much is done by the language compiler and how much is done by the JIT compiler, but the end result would be practically the same.

嗫嚅 2024-08-14 02:05:57

泛型可以通过减少转换和转换次数来提高性能。自动装箱(分别针对引用类型和值类型)发生在方法体中的操作。

有关泛型的 MSDN 文章

“无通用”方法实现不会给您带来任何性能方面的提升,因为 JIT 将为您生成任何特定用例并积极缓存它们。

Generics can gain you some performance by reducing the number of casts & autoboxing (for reference and value types respectively) operations that occur in a method body.

MSDN article on generics.

"Generic-less" method implementations shouldn't gain you anything performance wise, as the JIT will handle generating any specific use cases for you and aggressively cache them.

可遇━不可求 2024-08-14 02:05:57

与非泛型等价物相比,泛型具有性能和运行时内存优势。例如,比较以下内容。

ArrayList arrayList = new ArrayList(new Byte[] { 1, 2, 3, 4, 5, 6, 7, 8} );

vs

List<Byte> byteList = new List<Byte> { 1, 2, 3, 4, 5, 6, 7, 8 };

ArrayList 将包含一个 object[] 的内部存储,其中每个元素都指向一个字节。因此,具有 32 位指针的列表的这一部分的理想内存是 8 * 4 + 8 = 40 字节。我说理想是因为它实际上更糟糕,因为装箱字节会有一些额外的开销,尽管我不知道到底有多少。

List 实现将包含 byte[],它只需要一个指向数组的指针加上 8 个字节,总共 12 个字节的内存,而无需装箱开销(无论是什么)。

除了内存差异之外,还存在装箱/拆箱值的性能成本。

对于引用类型来说差异较小,但即使如此,当从非泛型类型中取出数据时,您也会因不断地进行转换而受到成本损失。

这些差异是真实存在的,但会对大多数应用程序产生不可估量的影响。泛型的真正优点是编译时验证的可靠性更高,并且使用类型化值所产生的代码更简单。

在我看来,最好在适当和可能的情况下使用泛型。

山姆

Generics provide performance and runtime-memory advantages over non-generic equivalents. For example, compare the following.

ArrayList arrayList = new ArrayList(new Byte[] { 1, 2, 3, 4, 5, 6, 7, 8} );

vs

List<Byte> byteList = new List<Byte> { 1, 2, 3, 4, 5, 6, 7, 8 };

The ArrayList will contain an internal storage of object[] which with each element pointing to a byte. The ideal memory for this part of the list with 32 bit pointers is therefore 8 * 4 + 8 = 40 bytes. I say ideal 'cause it's actually worse since the boxed bytes will have some additional overhead, although I don't know exactly how much.

The List implementation will instead contain byte[] which will require just one pointer to the array plus the 8 bytes, for a total of 12 bytes of memory without the boxing overhead, whatever that is.

In addition to the memory differences, there is also the performance cost of boxing/unboxing the values.

The difference is less for reference types, but even there you'll have a cost penalty for casting constantly when taking data out of the non-generic type.

These differences are real, but will have immeasurable impact on most applications. The real advantage of generics is greater reliability of compile-time verification and simpler code that results from using typed values.

In my opinion it's best to use generics whenever appropriate and possible.

Sam

浮世清欢 2024-08-14 02:05:57

这个问题有道理。

唯一有保证的好处是更少的元数据或更少的运行时解析,并且显然更少的键盘输入和更多的 DRY。但是,这种情况与重新启动的 C++ 编译器和 Bjarne 抱怨多年的事情非常相似。绝对没有必要为指针容器生成膨胀。

无论如何,C# 泛型是一种非常糟糕的语言和运行时功能,可能会引起很多麻烦,并且没有接口几乎毫无用处。无法进行值类型比较这是设计相当糟糕的一个明显例子,以及跨翻译单元等的大量使用(无 typedef)的 DRY。

The question makes sense.

About the only guaranteed benefit you have is less metadata or less parsing by the runtime, and obviously less keyboard typing and more DRY. But, the case is pretty similar with retarted C++ compilers and the thing Bjarne complained about for ages. There is absolutely no need to generate bloat for say containers of pointers..

In any case, C# generics are a very poor language and runtime feature, can cause plenty of headaches and are without interfaces pretty much useless.. Inability to do value type comparison being one glaring example of rather poor design, as well as lots of DRY with usings (no typedef) across translation units etc.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文