Ta odpowiedź daje ładny, ogólny przegląd optymalizacji krótkich ciągów (SSO). Chciałbym jednak dowiedzieć się bardziej szczegółowo, jak to działa w praktyce, szczególnie w implementacji libc ++:
Jak krótki musi być ciąg znaków, aby kwalifikować się do logowania jednokrotnego? Czy to zależy od docelowej architektury?
W jaki sposób implementacja rozróżnia krótkie i długie ciągi podczas uzyskiwania dostępu do danych ciągu? Czy jest to tak proste, jak
m_size <= 16
flaga, która jest częścią innej zmiennej składowej? (Wyobrażam sobie, żem_size
lub jego część może być również używana do przechowywania danych ciągów).
Zadałem to pytanie specjalnie dla libc ++, ponieważ wiem, że korzysta z SSO, jest to nawet wspomniane na stronie domowej libc ++ .
Oto kilka obserwacji po spojrzeniu na źródło :
libc ++ można skompilować z dwoma nieco różnymi układami pamięci dla klasy string, zarządza to _LIBCPP_ALTERNATE_STRING_LAYOUT
flaga. Oba układy rozróżniają również maszyny little-endian i big-endian, co daje nam w sumie 4 różne warianty. Przyjmę "normalny" układ i little-endian w dalszej części.
Zakładając dalej, że size_type
są to 4 bajty, value_type
czyli 1 bajt, tak wyglądałyby pierwsze 4 bajty ciągu w pamięci:
// 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
Ponieważ rozmiar krótkiego ciągu znajduje się w górnych 7 bitach, należy go przesunąć podczas uzyskiwania do niego dostępu:
size_type __get_short_size() const {
return __r_.first().__s.__size_ >> 1;
}
Podobnie metoda pobierająca i ustawiająca dla pojemności długiego łańcucha używa __long_mask
do obejścia tego is_long
bitu.
Wciąż szukam odpowiedzi na swoje pierwsze pytanie, tj. Jaką wartość miałaby __min_cap
pojemność krótkich ciągów dla różnych architektur?
Inne implementacje bibliotek standardowych
Ta odpowiedź daje ładny przegląd std::string
układów pamięci w innych implementacjach bibliotek standardowych.
string
nagłówek tutaj , sprawdzam to w tej chwili :)