One of my many jobs is to ensure the platform managed APIs grow in a seamless and consistent way.  In many ways we are victims of our own success.  We have TONS of folks new to managed code (and OO design) building new APIs for the platform (the .NET Framework).  I have blogged before about the two day class I gave every quarter to help train folks.  But we also do extensive API reviews.  In these reviews we focus on simple scenarios and the shape of the APIs (rather than implementation details). 

 

Today we had a two hour review of some new low level APIs the windows team is building.  An interesting discussion point came up.  I was “encouraging” the team to make more frequent use of enums rather than magic constants.  Such as:  Foo (Colors.Red) rather than Foo (42).  [The particular example from today’s review was not nearly that blatant, but you get the idea].  The team justified their postion by saying that using an enum was costly because an additional type is loaded (the type for the enum). 

Now normally in the case I ask a simple question: Have you measured it?  Measurement is at the heart of perf work.  Random speculation is not (which is why I could never be a good perf guy;-)).  In many cases the answer is no and in fact the api is only ever called as part of a blocking network IO operation so the extra couple of milliseconds is pretty much noise.  Or something like that.  And in general I don’t think that loading one additional type is a big thing to worry about even if it was happening…

But this time I didn’t even have to ask that.   You see, at runtime, the CLR never loads the enum type.  The compiler emits the constant value of the enum.  (This is why you can never change the value after you ship).  Look at this simplistic example:

For the C# code:

Foo (Colors.Red);

The compiler generates:

  IL_0000:  ldc.i4.s   42

  IL_0001:  call       void ConsoleApplication1.Class1::Foo(valuetype ConsoleApplication1.Colors)

 

Notice the first line we do a load constant 42 instead of loading the Colors type and fishing out the Red value.  Just as performant as if we had passed in “42” but a LOT easier to understand.  Note that the reference to ConsoleApplication1.Colors in the type signature just specifies the method to call, again, no additional types need to be loaded.