2009-12-04 UPDATE: For profiling results on a number of the suggestions posted here, see below!
Consider the following very
Forgive me if I get something wrong here, I'm extrapolating from my knowledge of C++. For example, if you take ActivCode[0] of an empty string, in C++ you get a character whose value is zero.
Create a two dimensional array which you initialize once; the first dimension is the length of the code, the second is a character value. Populate with the enumeration value you'd like to return. Now your entire function becomes:
public static MarketDataExchange GetMarketDataExchange(string ActivCode) {
return LookupTable[ActivCode.Length][ActivCode[0]];
}
Lucky for you all the two-character codes are unique in the first letter compared to the other two-character codes.
Assuming every input will be a valid ActivCode
, that you can change the enumeration values and highly coupled to the GetHashCode
implementation:
enum MarketDataExchange
{
NONE,
NBBO = 371857150,
AMEX = 372029405,
BSE = 372029408,
BATS = -1850320644,
NSE = 372029407,
CHX = -284236702,
NYSE = 372029412,
ARCA = -734575383,
NASDAQ = 372029421,
NASDAQ_ADF = -1137859911,
CBOE = 372029419,
PHLX = 372029430,
DIRECTEDGE = 372029429
}
public static MarketDataExchange GetMarketDataExchange(string ActivCode)
{
if (ActivCode == null) return MarketDataExchange.NONE;
return (MarketDataExchange)ActivCode.GetHashCode();
}
Change the switch to switch on the HashCode() of the strings.
A couple of random thoughts, that may not all be applicable together:
Switch on the first character in the string, rather than the string itself, and do a sub-switch for strings which can contain more than one letter?
A hashtable would certainly guarantee O(1) retrieval, though it might not be faster for smaller numbers of comparisons.
Don't use strings, use enums or something like a flyweight instead. Using strings in this case seems a bit fragile anyway...
And if you really need it to be as fast as possible, why aren't you writing it in assembly? :)
With a valid input could use
if (ActivCode.Length == 0)
return MarketDataExchange.NBBO;
if (ActivCode.Length == 1)
return (MarketDataExchange) (ActivCode[0]);
return (MarketDataExchange) (ActivCode[0] | ActivCode[1] << 8);
Use the length of the code to create a unique value from that code instead of using GetHashCode() . It turns out there are no collisions if you use the first letter of the code shifted by the length of the code. This reduces the cost to two comparisons, one array index and one shift (on average).
public static MarketDataExchange GetMarketDataExchange(string ActivCode)
{
if (ActivCode == null)
return MarketDataExchange.NONE;
if (ActivCode.Length == 0)
return MarketDataExchange.NBBO;
return (MarketDataExchange)((ActivCode[0] << ActivCode.Length));
}
public enum MarketDataExchange
{
NONE = 0,
NBBO = 1,
AMEX = ('A'<<1),
BSE = ('B'<<1),
BATS = ('B'<<2),
NSE = ('C'<<1),
CHX = ('M'<<2),
NYSE = ('N'<<1),
ARCA = ('P'<<2),
NASDAQ = ('Q'<<1),
NASDAQ_ADF = ('Q'<<2),
CBOE = ('W'<<1),
PHLX = ('X'<<1),
DIRECTEDGE = ('Y'<<1),
}