Skip to content

Commit 08630ce

Browse files
serprexlance6716
andauthored
Use math/bits OnesCount to preallocate slices (#995)
* Use math/bits OnesCount to preallocate slices * trailing zeroes to scan flags * avoid epilogue loop --------- Co-authored-by: lance6716 <[email protected]>
1 parent c729fe3 commit 08630ce

File tree

2 files changed

+16
-18
lines changed

2 files changed

+16
-18
lines changed

client/conn.go

+7-12
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"context"
66
"crypto/tls"
77
"fmt"
8+
"math/bits"
89
"net"
910
"runtime"
1011
"runtime/debug"
@@ -557,13 +558,10 @@ func (c *Conn) execSend(query string) error {
557558
// separated by "|". Examples of capability names are CLIENT_DEPRECATE_EOF and CLIENT_PROTOCOL_41.
558559
// These are defined as constants in the mysql package.
559560
func (c *Conn) CapabilityString() string {
560-
var caps []string
561561
capability := c.capability
562-
for i := 0; capability != 0; i++ {
563-
field := uint32(1 << i)
564-
if capability&field == 0 {
565-
continue
566-
}
562+
caps := make([]string, 0, bits.OnesCount32(capability))
563+
for capability != 0 {
564+
field := uint32(1 << bits.TrailingZeros32(capability))
567565
capability ^= field
568566

569567
switch field {
@@ -642,13 +640,10 @@ func (c *Conn) CapabilityString() string {
642640
// StatusString returns a "|" separated list of status fields. Example status values are SERVER_QUERY_WAS_SLOW and SERVER_STATUS_AUTOCOMMIT.
643641
// These are defined as constants in the mysql package.
644642
func (c *Conn) StatusString() string {
645-
var stats []string
646643
status := c.status
647-
for i := 0; status != 0; i++ {
648-
field := uint16(1 << i)
649-
if status&field == 0 {
650-
continue
651-
}
644+
stats := make([]string, 0, bits.OnesCount16(status))
645+
for status != 0 {
646+
field := uint16(1 << bits.TrailingZeros16(status))
652647
status ^= field
653648

654649
switch field {

replication/row_event.go

+9-6
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"encoding/hex"
66
"fmt"
77
"io"
8+
"math/bits"
89
"strconv"
910
"strings"
1011
"time"
@@ -754,7 +755,7 @@ func (e *TableMapEvent) VisibilityMap() map[int]bool {
754755
if len(e.VisibilityBitmap) == 0 {
755756
return nil
756757
}
757-
ret := make(map[int]bool)
758+
ret := make(map[int]bool, len(e.VisibilityBitmap)*8)
758759
i := 0
759760
for _, field := range e.VisibilityBitmap {
760761
for c := 0x80; c != 0; c >>= 1 {
@@ -1146,15 +1147,17 @@ func (e *RowsEvent) decodeImage(data []byte, bitmap []byte, rowImageType EnumRow
11461147
}
11471148

11481149
row := make([]interface{}, e.ColumnCount)
1149-
skips := make([]int, 0)
11501150

11511151
// refer: https://github.com/alibaba/canal/blob/c3e38e50e269adafdd38a48c63a1740cde304c67/dbsync/src/main/java/com/taobao/tddl/dbsync/binlog/event/RowsLogBuffer.java#L63
11521152
count := 0
1153-
for i := 0; i < int(e.ColumnCount); i++ {
1154-
if isBitSet(bitmap, i) {
1155-
count++
1156-
}
1153+
col := 0
1154+
for ; col+8 <= int(e.ColumnCount); col += 8 {
1155+
count += bits.OnesCount8(bitmap[col>>3])
1156+
}
1157+
if col < int(e.ColumnCount) {
1158+
count += bits.OnesCount8(bitmap[col>>3] & byte((1<<(int(e.ColumnCount)-col))-1))
11571159
}
1160+
skips := make([]int, 0, int(e.ColumnCount)-count)
11581161
count = bitmapByteSize(count)
11591162

11601163
nullBitmap := data[pos : pos+count]

0 commit comments

Comments
 (0)