Этот ответ дает хороший общий обзор оптимизации коротких строк (SSO). Однако хотелось бы подробнее узнать, как это работает на практике, в частности в реализации libc ++:
Насколько короткой должна быть строка, чтобы иметь право на SSO? Это зависит от целевой архитектуры?
Как реализация различает короткие и длинные строки при доступе к строковым данным? Это так просто,
m_size <= 16или это флаг, являющийся частью какой-либо другой переменной-члена? (Я полагаю, что этоm_sizeили его часть также может использоваться для хранения строковых данных).
Я задал этот вопрос специально для libc ++, потому что знаю, что он использует SSO, об этом даже упоминается на домашней странице libc ++ .
Вот некоторые наблюдения после просмотра источника :
libc ++ может быть скомпилирован с двумя немного разными схемами памяти для строкового класса, это регулируется _LIBCPP_ALTERNATE_STRING_LAYOUTфлагом. Обе схемы также различают машины с прямым порядком байтов и обратным порядком байтов, что оставляет нам в общей сложности 4 различных варианта. В дальнейшем я буду предполагать "нормальную" раскладку и прямой порядок байтов.
Если предположить, что size_typeэто 4 байта, а это value_type1 байт, первые 4 байта строки будут выглядеть в памяти следующим образом:
// short string: (s)ize and 3 bytes of char (d)ata
sssssss0;dddddddd;dddddddd;dddddddd
^- is_long = 0
// long string: (c)apacity
ccccccc1;cccccccc;cccccccc;cccccccc
^- is_long = 1
Поскольку размер короткой строки находится в верхних 7 битах, при доступе к ней ее нужно сместить:
size_type __get_short_size() const {
return __r_.first().__s.__size_ >> 1;
}
Точно так же геттер и сеттер емкости длинной строки используются __long_maskдля обхода is_longбита.
Я все еще ищу ответ на свой первый вопрос, т.е. какое значение будет __min_capиметь емкость коротких строк для разных архитектур?
Другие реализации стандартной библиотеки
Этот ответ дает хороший обзор std::stringмакетов памяти в других реализациях стандартной библиотеки.
stringзаголовок здесь , я проверяю его в данный момент :)