diff --git a/Common/utils/benchmark_test.go b/Common/utils/benchmark_test.go index 7faacba..9ad9fcd 100644 --- a/Common/utils/benchmark_test.go +++ b/Common/utils/benchmark_test.go @@ -128,11 +128,11 @@ func BenchmarkSliceAllocationOriginal(b *testing.B) { func BenchmarkSliceAllocationOptimized(b *testing.B) { b.ResetTimer() for i := 0; i < b.N; i++ { - result := StringSlicePool.GetWithCapacity(50) + result := make([]string, 0, 50) for j := 0; j < 50; j++ { result = append(result, fmt.Sprintf("item-%d", j)) } - StringSlicePool.Put(result) + _ = result } } @@ -184,7 +184,7 @@ func TestMemoryUsage(t *testing.T) { }) } -// TestPoolReuse 测试对象池复用效果 +// TestPoolReuse 测试对象池复用效果(StringBuilderPool) func TestPoolReuse(t *testing.T) { // 重置计数器 pool := NewStringBuilderPool(1024) @@ -196,26 +196,11 @@ func TestPoolReuse(t *testing.T) { _ = result } - reused := pool.GetReusedCount() - t.Logf("字符串构建器复用次数: %d", reused) - if reused < 90 { - t.Errorf("复用率过低: %d/100", reused) - } + // GetReusedCount 方法已移除,无法测试复用次数 + t.Log("字符串构建器池测试完成") - // 测试切片池 - for i := 0; i < 100; i++ { - s := StringSlicePool.Get() - for j := 0; j < 10; j++ { - s = append(s, fmt.Sprintf("item-%d", j)) - } - StringSlicePool.Put(s) - } - - sliceReused := StringSlicePool.GetReusedCount() - t.Logf("切片池复用次数: %d", sliceReused) - if sliceReused < 90 { - t.Errorf("切片池复用率过低: %d/100", sliceReused) - } + // 切片池相关功能已移除,跳过该测试 + t.Log("切片池功能已移除") } // TestStringBuilderCorrectness 测试字符串构建器正确性 diff --git a/Common/utils/mappool.go b/Common/utils/mappool.go deleted file mode 100644 index 046bfb8..0000000 --- a/Common/utils/mappool.go +++ /dev/null @@ -1,183 +0,0 @@ -package utils - -import ( - "sync" - "sync/atomic" -) - -// MapPool Map对象池 -type MapPool[K comparable, V any] struct { - pool sync.Pool - reused int64 - maxSize int // 最大保留大小 -} - -// NewMapPool 创建新的Map池 -func NewMapPool[K comparable, V any](initSize, maxSize int) *MapPool[K, V] { - if initSize <= 0 { - initSize = 16 - } - if maxSize <= 0 { - maxSize = 1024 - } - - return &MapPool[K, V]{ - pool: sync.Pool{ - New: func() interface{} { - m := make(map[K]V, initSize) - return &m - }, - }, - maxSize: maxSize, - } -} - -// Get 获取Map -func (p *MapPool[K, V]) Get() map[K]V { - mapPtr := p.pool.Get().(*map[K]V) - m := *mapPtr - - // 清空现有内容 - for k := range m { - delete(m, k) - } - - atomic.AddInt64(&p.reused, 1) - return m -} - -// Put 归还Map -func (p *MapPool[K, V]) Put(m map[K]V) { - if m == nil { - return - } - - // 如果大小超过限制,不放回池中 - if len(m) > p.maxSize { - return - } - - p.pool.Put(&m) -} - -// GetWithCapacity 获取指定容量的Map -func (p *MapPool[K, V]) GetWithCapacity(capacity int) map[K]V { - m := p.Get() - - // 如果当前Map容量估计不足,重新创建 - // Go的map没有直接的容量概念,我们使用长度作为估算 - if capacity > p.maxSize { - p.Put(m) - return make(map[K]V, capacity) - } - - return m -} - -// GetReusedCount 获取复用次数 -func (p *MapPool[K, V]) GetReusedCount() int64 { - return atomic.LoadInt64(&p.reused) -} - -// 预定义的常用类型Map池 -var ( - StringToStringMapPool = NewMapPool[string, string](16, 512) - StringToIntMapPool = NewMapPool[string, int](16, 512) - IntToStringMapPool = NewMapPool[int, string](16, 512) - StringToStructMapPool = NewMapPool[string, struct{}](16, 512) - IntToStructMapPool = NewMapPool[int, struct{}](16, 512) -) - -// CreateStringSet 创建字符串集合(用于去重) -func CreateStringSet(slice []string) map[string]struct{} { - m := StringToStructMapPool.GetWithCapacity(len(slice)) - - for _, item := range slice { - m[item] = struct{}{} - } - - return m -} - -// CreateIntSet 创建整数集合(用于去重) -func CreateIntSet(slice []int) map[int]struct{} { - m := IntToStructMapPool.GetWithCapacity(len(slice)) - - for _, item := range slice { - m[item] = struct{}{} - } - - return m -} - -// ReturnStringSet 归还字符串集合 -func ReturnStringSet(m map[string]struct{}) { - StringToStructMapPool.Put(m) -} - -// ReturnIntSet 归还整数集合 -func ReturnIntSet(m map[int]struct{}) { - IntToStructMapPool.Put(m) -} - -// SetPool 专门用于集合操作的池 -type SetPool[T comparable] struct { - pool sync.Pool - reused int64 - maxSize int -} - -// NewSetPool 创建新的集合池 -func NewSetPool[T comparable](maxSize int) *SetPool[T] { - if maxSize <= 0 { - maxSize = 1024 - } - - return &SetPool[T]{ - pool: sync.Pool{ - New: func() interface{} { - m := make(map[T]struct{}, 16) - return &m - }, - }, - maxSize: maxSize, - } -} - -// Get 获取集合 -func (p *SetPool[T]) Get() map[T]struct{} { - mapPtr := p.pool.Get().(*map[T]struct{}) - m := *mapPtr - - // 清空现有内容 - for k := range m { - delete(m, k) - } - - atomic.AddInt64(&p.reused, 1) - return m -} - -// Put 归还集合 -func (p *SetPool[T]) Put(m map[T]struct{}) { - if m == nil { - return - } - - if len(m) > p.maxSize { - return - } - - p.pool.Put(&m) -} - -// GetReusedCount 获取复用次数 -func (p *SetPool[T]) GetReusedCount() int64 { - return atomic.LoadInt64(&p.reused) -} - -// 全局集合池 -var ( - StringSetPool = NewSetPool[string](1024) - IntSetPool = NewSetPool[int](1024) -) \ No newline at end of file diff --git a/Common/utils/slicepool.go b/Common/utils/slicepool.go index 3e20e1f..7b87089 100644 --- a/Common/utils/slicepool.go +++ b/Common/utils/slicepool.go @@ -1,92 +1,6 @@ package utils -import ( - "sort" - "sync" - "sync/atomic" -) -// SlicePool 泛型切片池 -type SlicePool[T any] struct { - pool sync.Pool - reused int64 - maxCap int // 最大保留容量 - initCap int // 初始化容量 -} - -// NewSlicePool 创建新的切片池 -func NewSlicePool[T any](initCap, maxCap int) *SlicePool[T] { - if initCap <= 0 { - initCap = 16 - } - if maxCap <= 0 { - maxCap = 1024 - } - - return &SlicePool[T]{ - pool: sync.Pool{ - New: func() interface{} { - slice := make([]T, 0, initCap) - return &slice - }, - }, - initCap: initCap, - maxCap: maxCap, - } -} - -// Get 获取切片 -func (p *SlicePool[T]) Get() []T { - slicePtr := p.pool.Get().(*[]T) - slice := *slicePtr - slice = slice[:0] // 重置长度但保留容量 - atomic.AddInt64(&p.reused, 1) - return slice -} - -// Put 归还切片 -func (p *SlicePool[T]) Put(slice []T) { - if slice == nil { - return - } - - // 如果容量超过最大限制,不放回池中 - if cap(slice) > p.maxCap { - return - } - - // 清空切片内容,避免内存泄露 - for i := range slice { - var zero T - slice[i] = zero - } - slice = slice[:0] - - p.pool.Put(&slice) -} - -// GetWithCapacity 获取指定容量的切片 -func (p *SlicePool[T]) GetWithCapacity(capacity int) []T { - slice := p.Get() - if cap(slice) < capacity { - // 如果容量不足,创建新的切片 - p.Put(slice) // 归还原来的 - return make([]T, 0, capacity) - } - return slice -} - -// GetReusedCount 获取复用次数 -func (p *SlicePool[T]) GetReusedCount() int64 { - return atomic.LoadInt64(&p.reused) -} - -// 预定义的常用类型切片池 -var ( - StringSlicePool = NewSlicePool[string](32, 1024) - IntSlicePool = NewSlicePool[int](32, 1024) - ByteSlicePool = NewSlicePool[byte](256, 64*1024) -) // DeduplicateStrings 高效字符串去重 - 简化版本 func DeduplicateStrings(slice []string) []string { @@ -108,73 +22,5 @@ func DeduplicateStrings(slice []string) []string { return result } -// DeduplicateInts 高效整数去重 -func DeduplicateInts(slice []int) []int { - if len(slice) <= 1 { - return slice - } - - result := IntSlicePool.Get() - defer IntSlicePool.Put(result) - - seen := make(map[int]struct{}, len(slice)) - - for _, item := range slice { - if _, exists := seen[item]; !exists { - seen[item] = struct{}{} - result = append(result, item) - } - } - - final := make([]int, len(result)) - copy(final, result) - return final -} -// SortAndDeduplicateStrings 排序并去重字符串 -func SortAndDeduplicateStrings(slice []string) []string { - if len(slice) <= 1 { - return slice - } - - // 先排序 - sort.Strings(slice) - - // 再去重(对已排序的切片更高效) - result := StringSlicePool.Get() - defer StringSlicePool.Put(result) - - result = append(result, slice[0]) - for i := 1; i < len(slice); i++ { - if slice[i] != slice[i-1] { - result = append(result, slice[i]) - } - } - - final := make([]string, len(result)) - copy(final, result) - return final -} -// SortAndDeduplicateInts 排序并去重整数 -func SortAndDeduplicateInts(slice []int) []int { - if len(slice) <= 1 { - return slice - } - - sort.Ints(slice) - - result := IntSlicePool.Get() - defer IntSlicePool.Put(result) - - result = append(result, slice[0]) - for i := 1; i < len(slice); i++ { - if slice[i] != slice[i-1] { - result = append(result, slice[i]) - } - } - - final := make([]int, len(result)) - copy(final, result) - return final -} \ No newline at end of file diff --git a/Common/utils/stringbuilder.go b/Common/utils/stringbuilder.go index 42e5d3c..22c7b12 100644 --- a/Common/utils/stringbuilder.go +++ b/Common/utils/stringbuilder.go @@ -1,7 +1,6 @@ package utils import ( - "fmt" "strconv" "strings" "sync" @@ -113,25 +112,7 @@ func (p *StringBuilderPool) JoinInts(slice []int, sep string) string { return builder.String() } -// FormatString 高效格式化字符串 -func (p *StringBuilderPool) FormatString(format string, args ...interface{}) string { - builder := p.Get() - defer p.Put(builder) - - // 预估容量 - estimatedLen := len(format) + len(args)*10 - if builder.Cap() < estimatedLen { - builder.Grow(estimatedLen) - } - - fmt.Fprintf(builder, format, args...) - return builder.String() -} -// GetReusedCount 获取复用次数统计 -func (p *StringBuilderPool) GetReusedCount() int64 { - return atomic.LoadInt64(&p.reused) -} // 全局字符串构建器池实例 var GlobalStringBuilderPool = NewStringBuilderPool(64 * 1024) @@ -145,6 +126,3 @@ func JoinInts(slice []int, sep string) string { return GlobalStringBuilderPool.JoinInts(slice, sep) } -func FormatString(format string, args ...interface{}) string { - return GlobalStringBuilderPool.FormatString(format, args...) -} \ No newline at end of file