Noticed while examining a bunch of profiles, that the for loop inside
(*CompactBitArry).NumTrueBitsBefore unnecessarily consumed a bunch of
time:
```shell
7.55s 9.88s (flat, cum) 93.38% of Total
240ms 250ms 88:func (bA *CompactBitArray) NumTrueBitsBefore(index int) int {
. . 89: onesCount := 0
70ms 340ms 90: max := bA.Count()
70ms 70ms 91: if index > max {
. . 92: index = max
. . 93: }
. . 94: // below we iterate over the bytes then over bits (in low endian) and count bits set to 1
2.54s 2.76s 95: for elem := 0; elem < len(bA.Elems); elem++ {
```
but we can use the native for loop that produces indices while iterating
over slices. Just by simply changing the form results in an improvement
```shell
7.50s 9.95s (flat, cum) 94.94% of Total
240ms 320ms 88:func (bA *CompactBitArray) NumTrueBitsBefore(index int) int {
. . 89: onesCount := 0
170ms 420ms 90: max := bA.Count()
90ms 100ms 91: if index > max {
. . 92: index = max
. . 93: }
. . 94: // below we iterate over the bytes then over bits (in low endian) and count bits set to 1
1.49s 1.62s 95: for elem := range bA.Elems {
```
and an improvement in CPU time
```shell
$ benchstat before.txt after.txt
name old time/op new time/op delta
NumTrueBitsBefore/new-8 13.3ns ± 1% 12.5ns ± 1% -6.07% (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 #13999
|
||
|---|---|---|
| .. | ||
| multisig | ||
| compact_bit_array_test.go | ||
| compact_bit_array.go | ||
| multisig.pb.go | ||
| types.go | ||