Esta resposta oferece uma boa visão geral de alto nível da otimização de string curta (SSO). Porém, gostaria de saber mais detalhadamente como funciona na prática, especificamente na implementação libc ++:
Quão curta a string deve ser para se qualificar para o SSO? Isso depende da arquitetura de destino?
Como a implementação distingue entre strings curtas e longas ao acessar os dados da string? É tão simples quanto
m_size <= 16
ou é um sinalizador que faz parte de alguma outra variável de membro? (Eu imagino quem_size
ou parte dele também possa ser usado para armazenar dados de string).
Eu fiz essa pergunta especificamente para libc ++ porque eu sei que ela usa SSO, isso é até mencionado na página inicial da libc ++ .
Aqui estão algumas observações após olhar para a fonte :
libc ++ pode ser compilado com dois layouts de memória ligeiramente diferentes para a classe string, isso é governado pelo _LIBCPP_ALTERNATE_STRING_LAYOUT
sinalizador. Ambos os layouts também distinguem entre máquinas little-endian e big-endian, o que nos deixa com um total de 4 variantes diferentes. Assumirei o layout "normal" e o little-endian no que segue.
Supondo ainda que size_type
sejam 4 bytes e value_type
1 byte, é assim que os primeiros 4 bytes de uma string seriam na memória:
// 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
Como o tamanho da string curta está nos 7 bits superiores, ela precisa ser alterada ao acessá-la:
size_type __get_short_size() const {
return __r_.first().__s.__size_ >> 1;
}
Da mesma forma, o getter e o setter para a capacidade de uma longa string usam __long_mask
para contornar o is_long
bit.
Ainda estou procurando uma resposta para minha primeira pergunta, ou seja, qual valor __min_cap
, a capacidade de strings curtas, teria para diferentes arquiteturas?
Outras implementações de biblioteca padrão
Esta resposta fornece uma boa visão geral dos std::string
layouts de memória em outras implementações de biblioteca padrão.
string
cabeçalho aqui , estou verificando no momento :)