diff --git a/pkg/registry/core/service/allocator/utils.go b/pkg/registry/core/service/allocator/utils.go index baf64506e09..c034f51e6c9 100644 --- a/pkg/registry/core/service/allocator/utils.go +++ b/pkg/registry/core/service/allocator/utils.go @@ -24,8 +24,8 @@ import ( // countBits returns the number of set bits in n func countBits(n *big.Int) int { var count int = 0 - for _, b := range n.Bytes() { - count += bits.OnesCount8(uint8(b)) + for _, w := range n.Bits() { + count += bits.OnesCount64(uint64(w)) } return count } diff --git a/pkg/registry/core/service/allocator/utils_test.go b/pkg/registry/core/service/allocator/utils_test.go index 4ba7dba8687..ec5c8f714eb 100644 --- a/pkg/registry/core/service/allocator/utils_test.go +++ b/pkg/registry/core/service/allocator/utils_test.go @@ -22,12 +22,18 @@ import ( ) func TestCountBits(t *testing.T) { + // bigN is an integer that occupies more than one big.Word. + bigN, ok := big.NewInt(0).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) + if !ok { + t.Fatal("Failed to set bigN") + } tests := []struct { n *big.Int expected int }{ {n: big.NewInt(int64(0)), expected: 0}, {n: big.NewInt(int64(0xffffffffff)), expected: 40}, + {n: bigN, expected: 1}, } for _, test := range tests { actual := countBits(test.n) @@ -36,3 +42,13 @@ func TestCountBits(t *testing.T) { } } } + +func BenchmarkCountBits(b *testing.B) { + bigN, ok := big.NewInt(0).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) + if !ok { + b.Fatal("Failed to set bigN") + } + for i := 0; i < b.N; i++ { + countBits(bigN) + } +}