tags:

views:

493

answers:

6

I'm interested in both style and performance considerations. My choice is to do either of the following ( sorry for the poor formatting but the interface for this site is not WYSIWYG ):

One:

string value = "ALPHA";

switch ( value.ToUpper() )
{
   case "ALPHA":
     // do somthing
     break;
   case "BETA":
     // do something else
     break;
   default:
     break;
}

Two:

public enum GreekLetters
{
    UNKNOWN= 0,
    ALPHA= 1,
    BETA = 2,
    etc...

}

string value = "Alpha";
GreekLetters letter = (GreekLetters)Enum.Parse( typeof( GreekLetters ), value.ToUpper() );

switch( letter )
{
   case GreekLetters.ALPHA:
      // do something
      break;
   case GreekLetters.BETA:
      // do something else
      break;
   default:
      break;
}

Personally, I prefer option TWO below, but I don't have any real reason other than basic style reasons. However, I'm not even sure there really is a style reason. Thanks for your input.

+6  A: 

The second option is marginally faster, as the first option may require a full string comparison. The difference will be too small to measure in most circumstances, though.

The real advantage of the second option is that you've made it explicit that the valid values for value fall into a narrow range. In fact, it will throw an exception at Enum.Parse if the string value isn't in the expected range, which is often exactly what you want.

JSBangs
The second option is slower because it requires a reflection hit to gather all fields and then an item by item comparison. I point to the framework source code in my answer to demonstrate this.
Jeff Moser
+1  A: 

I would definitely say #1. Enum.Parse() causes reflection which is relatively expensive. Plus, Enum.Parse() will throw an Exception if its not defined and since there's no TryParse() you'd need to wrap it in Try/Catch block

Chris Haas
+2  A: 

I can't comment on the performance part of the question but as for style I prefer option #2. Whenever I have a known set of values and the set is reasonably small (less than a couple of dozen or so) I prefer to use an enum. I find an enum is a lot easier to work with than a collection of string values and anyone looking at the code can quickly see what the set of allowed values is.

TLiebe
A: 

Not sure if there is a performance difference when switching on a string value versus an enum.

One thing to consider is would you need the values used for the case statements elsewhere in your code. If so, then using an enum would make more sense as you have a singular definition of the values. Const strings could also be used.

Nathen Silver
+2  A: 

Option #1 is faster because if you look at the code for Enum.Parse, you'll see that it goes through each item one by one, looking for a match. In addition, there is less code to maintain and keep consistent.

One word of caution is that you shouldn't use ToUpper, but rather ToUpperInvariant() because of Turkey Test issues.

If you insist on Option #2, at least use the overload that allows you to specify to ignore case. This will be faster than converting to uppercase yourself. In addition, be advised that the Framework Design Guidelines encourage that all enum values be PascalCase instead of SCREAMING_CAPS.

Jeff Moser
Seriously, SCREAMING_CAPS is sooooo C++
Neil N
A: 

This actually depends on the number of items in the enum, and you would have to test it for each specific scenario - not that it is likely to make a big difference. But it is a great question.

With very few values, the Enum.Parse is going to take more time than anything else in either example, so the second should be slower.

With enough values, the switch statement will be implemented as a hashtable, which should work the same speed with strings and enums, so again, Enum.Parse will probably make the second solution slower, but not by relatively as much.

Somewhere in the middle, I would expect the cost of comparing strings being higher than comparing enums would make the first solution faster.

I wouldn't even be surprised if it were different on different compiler versions or different options.

Brad