C语言中如何优化字符串的SSO操作?
摘要:小字符串优化 SSO 能允许速度慢的话 就不要用C++了 减少字符串的使用 就是减少内存分配 STL对于小到一定程度的字符串 可以只分配一小块基于栈的缓冲区 而不是堆分配的 所以如果你有一个非常小的字符串
小字符串优化 SSO
能允许速度慢的话 就不要用C++了 减少字符串的使用 就是减少内存分配
STL对于小到一定程度的字符串 可以只分配一小块基于栈的缓冲区 而不是堆分配的 所以如果你有一个非常小的字符串 就不用考虑const char*或者试图微观管理 优化你的代码 因为STL本来就不会做堆分配
为了防止堆分配 可能你使用const char* name = "Miku"; 但其实这里并没有堆分配 这符合C++的小字符串 只存储在一个静态分配的缓冲区 不会使用堆内存
右键代码中的std::string 查看定义 到达这一行 using string = basic_string<char, char_traits, allocator>; 所以string其实是basic_string的别名 右键basic_string 转到定义 就到达了basic_string类
如何阅读STL源码
我们就以std::string为例 学习如何阅读STL源码 重点关注小字符串优化机制
右键头文件#include 的string 转到文档 就到达了头文件 也就几百行 说明这其中是没有具体实现的 在代码中任何一处右键 - 大纲显示 - 折叠到定义 就可以看到这里是一些全局函数 比如getline stoi to_string
回到文件开头 可以看到include了一些头文件 约定x前缀表示核心容器实现 右键转到文档 这份文件有5000多行 继续右键折叠到定义
ctrl+F 打开匹配大小写 搜索class string 没有找到 搜索string 看到了非常多的basic_string_view basic_string 直到我们看到了一行_EXPORT_STD using string = basic_string<char, char_traits, allocator>; 于是我们知道 string就是basic_string的别名 于是继续搜索class basic_string 发现这是一个2000多行的类 就是我们要找的核心实现 很多STL的核心实现都是以basic_命名
_EXPORT_STD template <class _Elem, class _Traits = char_traits<_Elem>, class _Alloc = allocator<_Elem>>
class basic_string {
}
这是一个模板类 拿到任何一个类 我们都需要查看
核心成员变量
构造函数 析构函数
内存管理策略
常用操作
可以先按ctrl+K ctrl+K 为这个basic_string类添加一个书签
往下看 找到一个不接收任何参数的构造函数
basic_string() noexcept(is_nothrow_default_constructible_v<_Alty>) : _Mypair(_Zero_then_variadic_args_t{}) {
_Mypair._Myval2._Alloc_proxy(_GET_PROXY_ALLOCATOR(_Alty, _Getal()));
_Tidy_init();
}
不禁要问 _Mypair是什么 右键_Mypair 速览定义
_Compressed_pair<_Alty, _Scary_val> _Mypair;
用同样的方式查看_Compressed_pair类 注释里写store a pair of values, deriving from empty first 在本例中它存储了一对_Alty _Scary_val 我们对_Scary_val右键速览定义 发现基本上就是_String_val的别名
_String_val是一个类 是实现小字符串优化的核心
class _String_val : public _Container_base {
public:
using value_type = typename _Val_types::value_type;
using size_type = typename _Val_types::size_type;
using difference_type = typename _Val_types::difference_type;
using pointer = typename _Val_types::pointer;
using const_pointer =
