Skip to content

Commit 02b8976

Browse files
committed
Optimize BitOps
1 parent da00197 commit 02b8976

File tree

1 file changed

+20
-16
lines changed

1 file changed

+20
-16
lines changed

BitFaster.Caching/BitOps.cs

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ public static uint CeilingPowerOfTwo(uint x)
4444
x |= x >> 16;
4545
return x + 1;
4646
#else
47-
return 1u << -BitOperations.LeadingZeroCount(x - 1);
47+
return BitOperations.RoundUpToPowerOf2(x);
4848
#endif
4949
}
5050

@@ -66,7 +66,7 @@ internal static ulong CeilingPowerOfTwo(ulong x)
6666
x |= x >> 32;
6767
return x + 1;
6868
#else
69-
return 1ul << -BitOperations.LeadingZeroCount(x - 1);
69+
return BitOperations.RoundUpToPowerOf2(x);
7070
#endif
7171
}
7272

@@ -113,14 +113,16 @@ public static int BitCount(int x)
113113
public static int BitCount(uint x)
114114
{
115115
#if NETSTANDARD2_0
116-
var count = 0;
117-
while (x != 0)
118-
{
119-
count++;
120-
x &= x - 1; //walking through all the bits which are set to one
121-
}
116+
const uint c1 = 0x_55555555u;
117+
const uint c2 = 0x_33333333u;
118+
const uint c3 = 0x_0F0F0F0Fu;
119+
const uint c4 = 0x_01010101u;
122120

123-
return count;
121+
x -= (x >> 1) & c1;
122+
x = (x & c2) + ((x >> 2) & c2);
123+
x = (((x + (x >> 4)) & c3) * c4) >> 24;
124+
125+
return (int)x;
124126
#else
125127
return BitOperations.PopCount(x);
126128
#endif
@@ -144,14 +146,16 @@ public static int BitCount(long x)
144146
public static int BitCount(ulong x)
145147
{
146148
#if NETSTANDARD2_0
147-
var count = 0;
148-
while (x != 0)
149-
{
150-
count++;
151-
x &= x - 1; //walking through all the bits which are set to one
152-
}
149+
const ulong c1 = 0x_55555555_55555555ul;
150+
const ulong c2 = 0x_33333333_33333333ul;
151+
const ulong c3 = 0x_0F0F0F0F_0F0F0F0Ful;
152+
const ulong c4 = 0x_01010101_01010101ul;
153+
154+
x -= (x >> 1) & c1;
155+
x = (x & c2) + ((x >> 2) & c2);
156+
x = (((x + (x >> 4)) & c3) * c4) >> 56;
153157

154-
return count;
158+
return (int)x;
155159
#else
156160
return BitOperations.PopCount(x);
157161
#endif

0 commit comments

Comments
 (0)