这个答案给出了短字符串优化(SSO)的一个很好的高级概述。但是,我想更详细地了解它在实践中是如何工作的,特别是在libc++实现中:
>
在访问字符串数据时,实现如何区分短字符串和长字符串?它是像 我是专门针对libc++提出这个问题的,因为我知道它使用SSO,甚至在libc++主页上也提到了这个问题。 下面是看过出处后的一些观察: LibC++可以使用string类的两种略有不同的内存布局进行编译,这是由 进一步假设 由于短串的大小在上面的7位,因此在访问它时需要对其进行移位: 类似地,长字符串容量的getter和setter使用 我仍然在寻找我的第一个问题的答案,即 其他标准库实现 这个答案很好地概述了其他标准库实现中的// 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
size_type __get_short_size() const {
return __r_.first().__s.__size_ >> 1;
}
LibC++
对于不同的体系结构,__min_cap(短字符串的容量)会取什么值?
在简短的形式中,有3个单词需要使用:
这样就剩下3个字减去2个字节来存储一个短字符串(即没有分配的最大
在32位机器上,短字符串中可以容纳10个字符。sizeof(字符串)为12。
在64位机器上,短字符串中可以容纳22个字符。sizeof(字符串)为24。
一个主要的设计目标是最小化
长表单至少需要3个字来存储数据指针,大小和容量。因此,我将缩写形式限制在那三个相同的单词上。有人建议,4字大小的OF可能具有更好的性能。我没有测试过那个设计选择。
_libcpp_abi_alternate_string_layout
有一个名为
struct __long
{
size_type __cap_;
size_type __size_;
pointer __data_;
};
致:
struct __long
{
pointer __data_;
size_type __size_;
size_type __cap_;
};
这种改变的动机是相信将
这面旗帜应该小心使用。它是一个不同的ABI,如果不小心与使用不同设置
我建议仅由libc++供应商更改此标志。
libc++实现有点复杂,我将忽略它的替代设计,并假设一个小端点计算机:
template <...>
class basic_string {
/* many many things */
struct __long
{
size_type __cap_;
size_type __size_;
pointer __data_;
};
enum {__short_mask = 0x01};
enum {__long_mask = 0x1ul};
enum {__min_cap = (sizeof(__long) - 1)/sizeof(value_type) > 2 ?
(sizeof(__long) - 1)/sizeof(value_type) : 2};
struct __short
{
union
{
unsigned char __size_;
value_type __lx;
};
value_type __data_[__min_cap];
};
union __ulx{__long __lx; __short __lxx;};
enum {__n_words = sizeof(__ulx) / sizeof(size_type)};
struct __raw
{
size_type __words[__n_words];
};
struct __rep
{
union
{
__long __l;
__short __s;
__raw __r;
};
};
__compressed_pair<__rep, allocator_type> __r_;
}; // basic_string
注意:
好吧,这是相当原始的,所以让我们检查一下机械!在内部,许多函数将调用
bool __is_long() const _NOEXCEPT
{ return bool(__r_.first().__s.__size_ & __short_mask); }
// __r_.first() -> __rep const&
// .__s -> __short const&
// .__size_ -> unsigned char
老实说,我不太确定这是标准的C++(我知道