tags:

views:

97

answers:

5

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?

+1  A: 

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.

Guffa
A: 

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.

Kevin Montrose
A: 

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

Sam
A: 

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.

rama-jka toti
-1: There would be *more* metadata, and the implementation would actually be more bloated.
280Z28
hmm.. so if all clients now have to write StringList, IntList, Z28280List, and x other, as well as MinusOneList, I end up with less metadata than with List<T>.. Is that math?
rama-jka toti
Similar applies to JIT generated code size, the thunk, a no brainer as well.. for master reference I'd pick up The C++ Programming Language and look at some odd chapter on specialisation where it is demonstrated how to circumvent dumb compilers and bloat.
rama-jka toti
+2  A: 

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.

Scott Wisniewski