golang字符串拼接效率

656 阅读1分钟

golang中字符串拼接性能依次是strings.builder>bytes.Buffer≈strings.Join>+ || fmt.Sprinf

拼接字符串都要经历“字符串创建、销毁、内存分配、数据拷贝等操作” 上面这里的差距主要体现在内存分配上 strings.builder比bytes.buffer性能好,是因为,bytes.buffer在往内存缓存中写入字符串时做了rune类型转换string时,产生了一个临时变量分配了内存,而string.builder是直接使用unsafe包将变量的类型转成了string.

而strings.Join看源码可以看出,最终使用的是string.builder,但在此之前也用到了临时变量,

而+或者fmt.Sprinf在连接前每个子串都会使用到临时变量

func (b *Builder) String() string {
   return *(*string)(unsafe.Pointer(&b.buf))
}
func (b *Buffer) String() string {
   if b == nil {
      // Special case, useful in debugging.
      return "<nil>"
   }
   return string(b.buf[b.off:])
}
func Join(elems []string, sep string) string {
   switch len(elems) {
   case 0:
      return ""
   case 1:
      return elems[0]
   }
   n := len(sep) * (len(elems) - 1)
   for i := 0; i < len(elems); i++ {
      n += len(elems[i])
   }

   var b Builder
   b.Grow(n)
   b.WriteString(elems[0])
   for _, s := range elems[1:] {
      b.WriteString(sep)
      b.WriteString(s)
   }
   return b.String()
}