Ответ
SBO (Small/String Buffer Optimization) — это оптимизация, которая позволяет избежать дорогостоящей аллокации памяти в куче (heap) для небольших объектов (чаще всего строк или срезов байт), размещая их напрямую на стеке (stack) внутри родительской структуры.
Как это работает:
В структуру встраивается массив фиксированного размера. Изначально срез (slice) указывает на этот встроенный массив. Если данные помещаются в этот массив, аллокации в куче не происходит. Если же данных становится больше, чем может вместить массив, создается новый, больший срез уже в куче.
Пример реализации в Go:
// Концептуальный пример, не реализация из stdlib
const smallBufferSize = 64
// Структура, использующая SBO
type Buffer struct {
buf []byte
smallBuf [smallBufferSize]byte // Встроенный буфер на стеке
}
func NewBuffer() *Buffer {
b := &Buffer{}
// Изначально срез указывает на встроенный массив.
// Аллокации в куче не происходит.
b.buf = b.smallBuf[:0]
return b
}
func (b *Buffer) Write(p []byte) {
// ... логика, которая либо пишет в b.buf (если есть место),
// либо аллоцирует новый срез в куче, если места не хватает.
}
Преимущества:
- Снижение нагрузки на сборщик мусора (GC): Меньше объектов в куче — меньше работы для GC.
- Увеличение производительности: Аллокация на стеке значительно быстрее, чем в куче.
- Улучшение локальности данных: Данные хранятся рядом с самой структурой, что может улучшить производительность кэша CPU.
Когда полезно:
- Для часто создаваемых и уничтожаемых объектов с коротким временем жизни.
- При работе с данными, размер которых в большинстве случаев не превышает небольшой порог (например, до 1KB).