One of the great things about being here at this PDC is the way that you get information straight from the source. For example, going to a presentation on the new C# features is cool – going to a presentation on those features that’s being given by the guy who designed the language is even better.
Anders Heijlsberg (the man so smart I can’t even spell his last name) did a really fantastic job and gave a very consumable presentation. Even though he cruised through fairly abstract academic topics like the difference between open and closed generic types, anonymous procedures, and outer local variable captures, I still felt that the presentation was “down to earth” and pretty grokable by people who might have accidentally left their PhD’s in their hotel rooms.
Once I get my Whidbey box set up, I’m going to be playing around quite a bit with this stuff. I’ll post code samples when I create them.
Exciting data point: the implementation of generics in Whidbey are REALLY fast. Anders did a demo comparing an ArrayList to a List<int>, with the generic implementation being almost twice as fast as the loosely-typed implementation. The performance gains come from the fact that since the JITed is operating directly on integer data types there’s no boxing/unboxing overhead. And since all retrieval operation on the generic type are typed in terms of int’s, the generic implementation eliminates the need to downcast as well as the associated performance cost thereof.
The generic implementation is really heavily optimized to reduce code footprint. Unlike generic implementations that do compile-time type expansion (like *cough* Java), there’s always only one instance of a given generic type present in the IL – in other words, the IL is itself generic. Actual instances of a closed generic type are created only as necessary – so if you declare List<int>, List<float>, List<Foo> and List<Bar> but only do a runtime instantiation of List<Bar>, the other 3 closed typed won’t incur any additional performance overhead. This is a substantial improvement over C++ templates, which did compile-time expansion. In the C++ world, the compiler would have actually instantiated those other types even though they were never actually used at runtime.
Once a particular closed generic type is actually instantiated at runtime, there are additional optimizations that the runtime takes to reduce the amount of overhead required to JIT-compile the code. When the closed generic type is parameterized in terms of value types, the JIT will generate new code for that type. If it didn’t do this, you’d incur the overhead of boxing and runtime performance would suffer. However, when a closed generic type is parameterized only in terms of reference types, the JIT will reuse the native instructions for all possible instantiations of that generic. That is, List<Foo>, List<Bar>, and List<Baz> will actually all use the same JITed code underneath the hood.
There are other cool things in store as well…briefly, the implementation of anonymous proc’s in Whidbey are full-on lambda forms with full support for capturing outer local variables. I can’t wait to start playing with these!
