Esta respuesta ofrece una buena descripción general de alto nivel de la optimización de cadenas cortas (SSO). Sin embargo, me gustaría saber con más detalle cómo funciona en la práctica, específicamente en la implementación de libc ++:
¿Qué tan corta debe ser la cadena para calificar para SSO? ¿Depende esto de la arquitectura de destino?
¿Cómo distingue la implementación entre cadenas cortas y largas al acceder a los datos de la cadena? ¿Es tan simple como
m_size <= 16
una bandera que forma parte de alguna otra variable miembro? (Me imagino quem_size
o parte de él también podría usarse para almacenar datos de cadena).
Hice esta pregunta específicamente para libc ++ porque sé que usa SSO, esto incluso se menciona en la página de inicio de libc ++ .
Aquí hay algunas observaciones después de mirar la fuente :
libc ++ se puede compilar con dos diseños de memoria ligeramente diferentes para la clase de cadena, esto se rige por la _LIBCPP_ALTERNATE_STRING_LAYOUT
bandera. Ambos diseños también distinguen entre máquinas little-endian y big-endian, lo que nos deja con un total de 4 variantes diferentes. Asumiré el diseño "normal" y el little-endian en lo que sigue.
Suponiendo además que size_type
son 4 bytes y que value_type
es 1 byte, así se verían los primeros 4 bytes de una cadena en la memoria:
// 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
Dado que el tamaño de la cadena corta está en los 7 bits superiores, debe cambiarse al acceder a ella:
size_type __get_short_size() const {
return __r_.first().__s.__size_ >> 1;
}
De manera similar, el captador y el configurador de la capacidad de una cadena larga se utilizan __long_mask
para trabajar alrededor de la is_long
broca.
Todavía estoy buscando una respuesta a mi primera pregunta, es decir, ¿qué valor tomaría __min_cap
la capacidad de cadenas cortas para diferentes arquitecturas?
Otras implementaciones de bibliotecas estándar
Esta respuesta ofrece una buena descripción general de std::string
los diseños de memoria en otras implementaciones de bibliotecas estándar.
string
encabezado aquí , lo estoy revisando en este momento :)