From 0f1142d434395eb9d36d668bfa307343292c3cd2 Mon Sep 17 00:00:00 2001 From: bandl <1658002533@qq.com> Date: Thu, 4 Nov 2021 16:31:55 +0800 Subject: [PATCH 1/2] perf(structure-value): perf set bit --- pkg/structure/value.go | 28 +++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/pkg/structure/value.go b/pkg/structure/value.go index ea779fd..36a5a26 100644 --- a/pkg/structure/value.go +++ b/pkg/structure/value.go @@ -147,26 +147,28 @@ func (v *Value) ChangeValueLength(f func()) UpdateLength { func (v *Value) SetByte(offset int, val bool) { v.onType = DynamicNull // 位图使用无类型 - b := byte(0) - if val { - b = byte(1) - } - if v.length >= offset { - v.val[offset] = b + // 扩容 + if len(v.val) <= offset/8 { + newByte := make([]byte, (offset/8)+1) + copy(newByte, v.val[:len(v.val)]) + v.val = newByte + v.length = len(v.val) + } + if val { + // true 位 + v.val[offset/8] |= (0b1 << (offset % 8)) return } - newByte := make([]byte, offset+1) - newByte[offset] = b - copy(newByte, v.val[:v.length]) - v.val = newByte - v.length = len(newByte) + // false 位 + v.val[offset/8] ^= (0b1 << (offset % 8)) } func (v *Value) GetByte(offset int) (bool, error) { - if v.length >= offset { - return v.val[offset] == byte(1), nil + if len(v.val) >= offset/8 { + // 采用 & 来运算 是否为 true + return v.val[offset/8]&(0b1<<(offset%8)) != 0, nil } return false, errorx.New("the maximum length is exceeded") From 2ed75832ba10d4d68375f53fcf3e07e055ea6b75 Mon Sep 17 00:00:00 2001 From: bandl <1658002533@qq.com> Date: Thu, 4 Nov 2021 16:32:17 +0800 Subject: [PATCH 2/2] test(structure-val): add perf test --- pkg/structure/value_test.go | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pkg/structure/value_test.go b/pkg/structure/value_test.go index f0142d4..9ee011e 100644 --- a/pkg/structure/value_test.go +++ b/pkg/structure/value_test.go @@ -1,6 +1,7 @@ package structure import ( + "fmt" "strconv" "testing" @@ -126,4 +127,20 @@ func TestValue_SetByte(t *testing.T) { v, err = value.GetByte(10001) require.NoError(t, err) require.Equal(t, v, true) + require.Equal(t, value.GetSize(), (10001/8)+1+16) +} + +func TestValue_SetByteWei(t *testing.T) { + k := make([]byte, 100) + offset := 700 + k[offset/8] = 0b00000001 + k[offset/8] |= 0b1 << (offset % 8) + + fmt.Printf("%b\n", k[offset/8]) + + fmt.Printf("%v", (k[offset/8]&(0b1<<(offset%8))) != 0) + + k[offset/8] ^= 0b1 << (offset % 8) + + fmt.Printf("%v", (k[offset/8]&(0b1<<(offset%8))) != 0) }