package utils import ( "strconv" "strings" "sync" "sync/atomic" ) // StringBuilderPool 字符串构建器池 type StringBuilderPool struct { pool sync.Pool reused int64 // 复用计数器 maxSize int // 最大保留大小,防止内存无限增长 } // NewStringBuilderPool 创建新的字符串构建器池 func NewStringBuilderPool(maxSize int) *StringBuilderPool { if maxSize <= 0 { maxSize = 64 * 1024 // 默认64KB最大保留大小 } return &StringBuilderPool{ pool: sync.Pool{ New: func() interface{} { return &strings.Builder{} }, }, maxSize: maxSize, } } // Get 获取字符串构建器 func (p *StringBuilderPool) Get() *strings.Builder { builder := p.pool.Get().(*strings.Builder) builder.Reset() // 清空内容但保留容量 atomic.AddInt64(&p.reused, 1) return builder } // Put 归还字符串构建器 func (p *StringBuilderPool) Put(builder *strings.Builder) { if builder == nil { return } // 如果容量超过最大限制,不放回池中以避免内存泄露 if builder.Cap() > p.maxSize { return } p.pool.Put(builder) } // JoinStrings 高效连接字符串切片 func (p *StringBuilderPool) JoinStrings(slice []string, sep string) string { if len(slice) == 0 { return "" } if len(slice) == 1 { return slice[0] } builder := p.Get() defer p.Put(builder) // 预估容量:所有字符串长度 + 分隔符长度 var totalLen int for _, s := range slice { totalLen += len(s) } totalLen += len(sep) * (len(slice) - 1) // 如果当前容量不足,预先增长 if builder.Cap() < totalLen { builder.Grow(totalLen) } builder.WriteString(slice[0]) for i := 1; i < len(slice); i++ { builder.WriteString(sep) builder.WriteString(slice[i]) } return builder.String() } // JoinInts 高效连接整数切片 func (p *StringBuilderPool) JoinInts(slice []int, sep string) string { if len(slice) == 0 { return "" } if len(slice) == 1 { return strconv.Itoa(slice[0]) } builder := p.Get() defer p.Put(builder) // 预估容量:平均每个整数4字符 + 分隔符 estimatedLen := len(slice)*4 + len(sep)*(len(slice)-1) if builder.Cap() < estimatedLen { builder.Grow(estimatedLen) } builder.WriteString(strconv.Itoa(slice[0])) for i := 1; i < len(slice); i++ { builder.WriteString(sep) builder.WriteString(strconv.Itoa(slice[i])) } return builder.String() } // 全局字符串构建器池实例 var GlobalStringBuilderPool = NewStringBuilderPool(64 * 1024) // 便捷函数,使用全局池 func JoinStrings(slice []string, sep string) string { return GlobalStringBuilderPool.JoinStrings(slice, sep) } func JoinInts(slice []int, sep string) string { return GlobalStringBuilderPool.JoinInts(slice, sep) }