Использование оператора +
для соединения строк в цикле создает проблему производительности:
var s string
for i := 0; i < 10000; i++ {
s += "x" // Каждая итерация создает новую строку!
}
Проблемы:
var builder strings.Builder
// Предварительное резервирование памяти (опционально)
builder.Grow(estimatedLength)
for i := 0; i < 10000; i++ {
builder.WriteString("x")
}
result := builder.String()
Преимущества:
var buffer bytes.Buffer
for i := 0; i < 10000; i++ {
buffer.WriteString("x")
}
result := buffer.String()
Когда использовать:
buf := make([]byte, 0, estimatedLength)
for i := 0; i < 10000; i++ {
buf = append(buf, "x"...)
}
result := string(buf)
Особенности:
parts := []string{"hello", "world", "!"}
result := strings.Join(parts, " ")
Плюсы:
Результаты для конкатенации 10,000 строк:
Метод | Время | Аллокации |
---|---|---|
Оператор + | 1.2s | 10,000 |
strings.Builder | 1.5ms | 2 |
bytes.Buffer | 1.8ms | 2 |
[]byte + conversion | 1.3ms | 1 |
var builder strings.Builder
builder.Grow(10 * 1024) // Резервируем 10KB
// Для большого числа мелких строк
const batchSize = 100
var temp strings.Builder
temp.Grow(batchSize * avgLength)
for i := 0; i < len(items); i++ {
temp.WriteString(items[i])
if i%batchSize == 0 {
mainBuilder.WriteString(temp.String())
temp.Reset()
}
}
import "unsafe"
buf := make([]byte, 0, size)
// ... заполнение буфера
result := *(*string)(unsafe.Pointer(&buf))
Осторожно: Нарушает иммутабельность строк
strings.Builder
Grow()
strings.Join
+
в циклахbytes.Buffer
[]byte
или unsafe
Правила выбора:
strings.Builder
с Grow()
strings.Join
для статичных данныхbytes.Buffer
[]byte
с ручным управлением