How would you make this switch statement as fast as possible?

后端 未结 21 2016
别那么骄傲
别那么骄傲 2021-01-30 04:17

2009-12-04 UPDATE: For profiling results on a number of the suggestions posted here, see below!


The Question

Consider the following very

21条回答
  •  隐瞒了意图╮
    2021-01-30 04:58

    All your strings are at most 2 chars long, and ASCII, so we can use 1 byte per char. Furthermore, more likely than not, they also never can have \0 appear in them (.NET string allows for embedded null characters, but many other things don't). With that assumption, we can null-pad all your strings to be exactly 2 bytes each, or an ushort:

    ""   -> (byte) 0 , (byte) 0   -> (ushort)0x0000
    "A"  -> (byte)'A', (byte) 0   -> (ushort)0x0041
    "B"  -> (byte)'B', (byte) 0   -> (ushort)0x0042
    "BT" -> (byte)'B', (byte)'T'  -> (ushort)0x5442
    

    Now that we have a single integer in a relatively (64K) short range, we can use a lookup table:

    MarketDataExchange[] lookup = {
        MarketDataExchange.NBBO, 
        MarketDataExchange.NONE, 
        MarketDataExchange.NONE, 
        ...
        /* at index 0x041 */
        MarketDataExchange.AMEX,
        MarketDataExchange.BSE,
        MarketDataExchange.NSE,
        ...
    };
    

    Now, obtaining the value given a string is:

    public static unsafe MarketDataExchange GetMarketDataExchange(string s)
    {
       // Assume valid input
       if (s.Length == 0) return MarketDataExchange.NBBO;
    
       // .NET strings always have '\0' after end of data - abuse that
       // to avoid extra checks for 1-char strings. Skip index checks as well.
       ushort hash;
       fixed (char* data = s)
       {
           hash = (ushort)data[0] | ((ushort)data[1] << 8);
       }
    
       return lookup[hash];
    }
    

提交回复
热议问题