主要观点:比较了std::string
的三种主要实现(gcc、msvc、clang)在一些常见操作上的复杂度及其他特性,包括检测字符串大小、获取数据、获取大小、判断是否为空、获取容量等方面,还提及了静态初始化以及混合状态等情况,并总结在表格中。
关键信息:
- gcc 实现中
string
结构体包含char* ptr
、size_t size
和联合union { size_t capacity; char buf[16]; }
等成员,通过比较ptr
和buf
判断字符串大小等。 - msvc 实现中
string
结构体包含联合union { char* ptr; char buf[16]; }
、size_t size
和size_t capacity
等成员,通过比较capacity
和 15 判断字符串大小等。 - clang 实现中
union string
包含大字符串结构体struct { size_t capacity; size_t size; char* ptr; } large
和小字符串结构体struct { unsigned char is_large:1; unsigned char size:7; char buf[sizeof(large) - 1]; } small
等成员,通过测试is_large
判断字符串大小等。 - 比较了三种实现在不同操作上的指令差异及性能优劣,如检测字符串大小的指令不同,获取数据、大小、容量等操作的速度也有差异,且 clang 在内存使用方面有优势,在某些特殊情况下(如静态初始化、
shrink_to_fit()
等)也有不同表现。
重要细节: - gcc 可通过重新排序成员优化检测字符串大小的指令,但会增加访问
ptr
的成本。 - clang 实现中获取
data()
、size()
等操作的指令较复杂,通过测试is_large
来决定使用大字符串或小字符串的相关成员。 - msvc 实现中使用容量来检测是否使用小字符串优化,在扩展字符串时
append(char)
操作有优势。 - 静态初始化时,gcc 的空字符串包含指针会引入数据段重定位,msvc 和 clang 则无指针且无重定位。
- 总结表格展示了三种实现在多个方面的特性对比。
更新内容:原文章中 clang 实现的“small/large”位方向有误,导致重新生成代码和新的代码优化结果;之前版本错误地认为shrink_to_fit()
在 gcc 上是无操作。
作者信息:Raymond Chen 参与 Windows 进化 30 多年,其网站 The Old New Thing 很受欢迎并出版相关书籍,偶尔在 Windows Dev Docs Twitter 账户上讲故事。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。