该答案很好地概述了短字符串优化(SSO)。但是,我想更详细地了解它在实践中如何工作,特别是在libc ++实现中:
要符合SSO要求,字符串必须多短?这取决于目标体系结构吗?
访问字符串数据时,实现如何区分短字符串和长字符串?它是否像
m_size <= 16
其他成员变量中的一部分一样简单?(我想它的m_size
一部分或一部分也可以用来存储字符串数据)。
我专门针对libc ++提出了这个问题,因为我知道它使用SSO,甚至在libc ++主页上也提到了这一点。
查看来源后,有一些观察结果:
libc ++可以为字符串类使用两个略有不同的内存布局进行编译,这由_LIBCPP_ALTERNATE_STRING_LAYOUT
标志控制。两种布局还区分了小端和大端机器,这使我们总共有4种不同的变体。在接下来的内容中,我将采用“普通”布局和小字节序。
进一步假设这size_type
是4个字节,也value_type
就是1个字节,这就是字符串的前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;
}
同样,长字串容量的getter和setter用来__long_mask
解决该is_long
位。
我仍在寻找第一个问题的答案,即__min_cap
对于不同的体系结构,短字符串的容量将获得什么价值?
其他标准库实现
该答案很好地概述了std::string
其他标准库实现中的内存布局。
string
标题,我目前正在检查中:)