← Назад к вопросам

Что такое SBO (Small Buffer Optimization)?

2.2 Middle🔥 131 комментариев
#Сборка и инструменты

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Small Buffer Optimization (SBO)

SBO — это оптимизация в стандартной библиотеке C++, которая позволяет хранить небольшие объекты (строки, векторы) без динамического выделения памяти. Вместо этого они хранятся в локальном буфере прямо внутри объекта контейнера.

Принцип работы

// Вместо выделения памяти на heap:
// "hello" -> heap выделение -> 5 байт + указатель + размер

// SBO хранит строку прямо в объекте std::string:
class string {
    char buffer[23];     // Локальный буфер (типично 23-24 байта)
    size_t size;
    size_t capacity;
    // Флаг или указатель для переключения между buffer и heap
};

Преимущества SBO

  1. Производительность — нет динамического выделения памяти, нет heap fragmentation
  2. Cache efficiency — данные находятся прямо в стеке, меньше cache misses
  3. Меньше индирекций — прямой доступ к данным вместо разыменования указателя
  4. Меньше работы garbage collector (если используется)

Пример с std::string

std::string short_str = "hello";     // Использует SBO, нет heap выделения
std::string long_str = "very long string that exceeds buffer size"; // heap

// При присваивании:
short_str = "world";  // Быстро, работает с локальным буфером

Пример с std::vector

Не все реализации используют SBO для vector, но некоторые это делают:

std::vector<int> small = {1, 2, 3};  // Может использовать SBO
std::vector<int> large(1000000);     // Точно heap

Размер буфера

Размер SBO зависит от реализации STL:

  • libstdc++ (GCC) — типично 15 байт для std::string (плюс нулевой терминатор = 16)
  • libc++ (Clang) — обычно 23 байта
  • MSVC STL — зависит от версии
std::string str;
std::cout << str.capacity();  // Выведет SSO capacity (часто 15, 16 или 23)

Когда срабатывает SBO

std::string s;
std::cout << s.capacity();  // Например, 15 (SBO включена)

for (int i = 0; i < 1000; ++i) {
    s += "x";  // После ~16 символов произойдёт переход на heap
}
std::cout << s.capacity();  // Теперь значительно больше 15

SSO (Small String Optimization)

SSO — это частный случай SBO для строк. Термины часто используются взаимозаменяемо:

  • SBO — общий термин для всех контейнеров
  • SSO — специфично для std::string

Практические последствия

  1. move-семантика — move SSO строки всё равно может скопировать буфер, если строка мала
  2. Размер объекта — объект string больше, чем простой указатель, так как содержит буфер
  3. Копирование — копирование малых строк часто быстрее, чем перемещение
std::string a = "hello";
std::string b = std::move(a);  // Может просто скопировать 5 байт вместо swap указателей

Проверка SBO в коде

#include <string>
#include <iostream>

int main() {
    std::string str;
    std::cout << "String capacity (SBO): " << str.capacity() << std::endl;
    str.resize(1000);
    std::cout << "String capacity (heap): " << str.capacity() << std::endl;
}

Вывод: SBO — это критическая оптимизация, которая делает std::string и другие контейнеры эффективными для маленьких объектов, избегая дорогостоящих выделений памяти и cache-промахов.

Что такое SBO (Small Buffer Optimization)? | PrepBro