Golang高性能优化

Posted by 淦 Blog on July 2, 2025

字符串

拼接

strings.Builder 用于通过Builder.Write方法高效地构建字符串。它可以最大限度地减少内存复制。零值可以直接使用。请勿复制非零的 Builder。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main

import (
	"fmt"
	"strings"
)

func main() {
    var b strings.Builder
    b.WriteString("Hello, ")
    b.WriteString("world!")
    result := b.String()
    fmt.Println(result) // 输出: Hello, world!
}

常用方法

表头 表头
WriteString(s string) 追加字符串 s
Write(p []byte) 追加字节切片
WriteRune(r rune) 追加一个 Unicode 字符
WriteByte(c byte) 追加一个字节
String() 返回当前构建的字符串
Len() 返回已写入的字节数
Reset() 清空内容,重用 Builder
Grow(n int) 提前分配至少 n 字节的空间
Cap() 返回底层缓冲区的容量(Go 1.20+)

性能优势

  • 避免多次分配:普通字符串拼接(如 a += b)每次都会分配新内存,Builder 只在需要时扩容。
  • 高效拼接:适合在循环中大量拼接字符串,性能远优于 + 或 fmt.Sprintf。
  • 零拷贝:内部维护一个可增长的字节切片,减少内存拷贝。

注意事项

  1. 不可拷贝,即不能通过赋值或作为值传递,否则会 panic。只能以指针或变量方式使用。
1
2
3
4
5
6
7
8
9
10
11
12
package main

import (
	"strings"
)

func main() {
	var a strings.Builder
	a.Write([]byte("testa"))
	var b = a
	b.Write([]byte("testb")) // 这里是复制后使用,所以会诱发panic
}
  1. 并发不安全,不能在多个 goroutine 中同时操作同一个 Builder。

  2. 如果能预估最终字符串长度,建议用 Grow(n) 提前分配,减少扩容次数。