Bu cevap , kısa dizgi optimizasyonuna (SSO) ilişkin güzel bir üst düzey genel bakış sunar. Bununla birlikte, pratikte, özellikle libc ++ uygulamasında nasıl çalıştığını daha ayrıntılı olarak bilmek isterim:
SSO'ya hak kazanmak için dizenin ne kadar kısa olması gerekir? Bu hedef mimariye bağlı mı?
Dize verilerine erişirken uygulama, kısa ve uzun dizeleri nasıl ayırt eder? Bu kadar basit mi
m_size <= 16
yoksa başka bir üye değişkeninin parçası olan bir bayrak mı? (Bununm_size
veya bir kısmının dize verilerini depolamak için de kullanılabileceğini düşünüyorum).
Bu soruyu özellikle libc ++ için sordum çünkü SSO kullandığını biliyorum, bu libc ++ ana sayfasında bile bahsediliyor .
İşte kaynağa baktıktan sonra bazı gözlemler :
libc ++, string sınıfı için iki farklı bellek düzeniyle derlenebilir, bu _LIBCPP_ALTERNATE_STRING_LAYOUT
bayrak tarafından yönetilir . Her iki düzen de küçük endian ve big-endian makineleri arasında ayrım yapıyor ve bu da bize toplam 4 farklı varyant bırakıyor. Aşağıda "normal" düzeni ve küçük endianı varsayacağım.
Bunun size_type
4 bayt ve value_type
1 bayt olduğunu varsayarsak , bu, bir dizenin ilk 4 baytı bellekte nasıl görünürdü:
// 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
Kısa dizinin boyutu üstteki 7 bitte olduğundan, ona erişirken kaydırılması gerekir:
size_type __get_short_size() const {
return __r_.first().__s.__size_ >> 1;
}
Benzer şekilde, uzun bir dizinin kapasitesi için alıcı ve ayarlayıcı __long_mask
, is_long
bit etrafında çalışmak için kullanır .
Hala ilk soruma bir cevap arıyorum, yani __min_cap
kısa dizelerin kapasitesi farklı mimariler için hangi değeri alır?
Diğer standart kitaplık uygulamaları
Bu cevap , std::string
diğer standart kütüphane uygulamalarındaki bellek düzenlerine güzel bir genel bakış sağlar .
string
başlığını burada bulabilirsiniz , şu anda kontrol ediyorum :)