Fastest way to enumerate through turned on bits of an integer

后端 未结 8 1199
暗喜
暗喜 2021-02-06 08:22

What\'s the fastest way to enumerate through an integer and return the exponent of each bit that is turned on? Have seen an example using << and another u

8条回答
  •  灰色年华
    2021-02-06 08:46

    The IEnumerable is not going to perform. Optimization of some examples in this topic:

    First one (fastest - 2.35 seconds for 10M runs, range 1..10M):

    static uint[] MulDeBruijnBitPos = new uint[32] 
    {
      0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, 
      31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9
    };
    
    static uint[] GetExponents(uint value)
    {
        uint[] data = new uint[32];
        int enabledBitCounter = 0;
    
        while (value != 0)
        {
            uint m = (value & (0 - value));
            value ^= m;
            data[enabledBitCounter++] = MulDeBruijnBitPos[(m * (uint)0x077CB531U) >> 27];
        }
    
        Array.Resize(ref data, enabledBitCounter);
        return data;
    }
    

    Another version (second fastest - 3 seconds for 10M runs, range 1..10M):

    static uint[] GetExponents(uint value)
    {
        uint[] data = new uint[32];
        int enabledBitCounter = 0;
    
        for (uint i = 0; value > 0; ++i)
        {
            if ((value & 1) == 1)
                data[enabledBitCounter++] = i;
            value >>= 1;
        }
    
        Array.Resize(ref data, enabledBitCounter);
        return data;
    }
    

提交回复
热议问题