API Review Process and Enums

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). o ns = "urn:schemas-microsoft-com:office:office" />

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.