crypto/types: optimize compact bit array one count (#9216)

By using bits.OnesCount8 instead of bitwise operations.

Benchmark result on Apple M1:

name                     old time/op    new time/op    delta
NumTrueBitsBefore/new-8    88.5ns ± 1%     9.1ns ± 0%  -89.68%  (p=0.000 n=10+10)

name                     old alloc/op   new alloc/op   delta
NumTrueBitsBefore/new-8     0.00B          0.00B          ~     (all equal)

name                     old allocs/op  new allocs/op  delta
NumTrueBitsBefore/new-8      0.00           0.00          ~     (all equal)

Fixes #9125
This commit is contained in:
Cuong Manh Le 2021-05-01 04:08:14 +07:00 committed by GitHub
parent f04b5dcb96
commit 72873a072f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 6 additions and 10 deletions

View File

@ -6,6 +6,7 @@ import (
"errors" "errors"
"fmt" "fmt"
"math" "math"
"math/bits"
"regexp" "regexp"
"strings" "strings"
) )
@ -85,23 +86,18 @@ func (bA *CompactBitArray) SetIndex(i int, v bool) bool {
// given index. e.g. if bA = _XX__XX, NumOfTrueBitsBefore(4) = 2, since // given index. e.g. if bA = _XX__XX, NumOfTrueBitsBefore(4) = 2, since
// there are two bits set to true before index 4. // there are two bits set to true before index 4.
func (bA *CompactBitArray) NumTrueBitsBefore(index int) int { func (bA *CompactBitArray) NumTrueBitsBefore(index int) int {
numTrueValues := 0 onesCount := 0
max := bA.Count() max := bA.Count()
if index > max { if index > max {
index = max index = max
} }
// below we iterate over the bytes then over bits (in low endian) and count bits set to 1 // below we iterate over the bytes then over bits (in low endian) and count bits set to 1
var i = 0
for elem := 0; ; elem++ { for elem := 0; ; elem++ {
for b := 7; b >= 0; b-- { if elem*8+7 >= index {
if i >= index { onesCount += bits.OnesCount8(bA.Elems[elem] >> (7 - (index % 8) + 1))
return numTrueValues return onesCount
}
i++
if (bA.Elems[elem]>>b)&1 == 1 {
numTrueValues++
}
} }
onesCount += bits.OnesCount8(bA.Elems[elem])
} }
} }