为何将std::string初始化为""比默认构造函数更高效?
为什么用空字符串字面量初始化std::string比默认构造更高效?
通常我们默认认为默认构造函数是创建空容器的最快方式,但实际测试发现,用空字符串字面量""初始化std::string反而有更优的性能表现。
测试代码如下:
#include <string> std::string make_default() { return {}; } std::string make_empty() { return ""; }
使用clang 16搭配libc++编译后,生成的汇编代码对比明显:
make_default(): mov rax, rdi xorps xmm0, xmm0 movups xmmword ptr [rdi], xmm0 mov qword ptr [rdi + 16], 0 ret make_empty(): mov rax, rdi mov word ptr [rdi], 0 ret
可以看到,return {}(默认构造)会清零总计24字节的内存,而return ""只需要清零2字节。这种差异的核心原因在于libc++对std::string的实现细节:
- libc++的
std::string采用了小字符串优化(SSO),64位系统下对象总大小为24字节,包含长度、容量(或SSO缓冲区)等字段。 - 默认构造函数会将整个24字节的对象内存全部清零,确保没有残留的垃圾数据,避免后续操作出现意外。
- 而通过空字符串字面量初始化时,调用的是
const char*版本的构造函数:该函数会先判断输入字符串的长度为0,此时只需要设置表示字符串长度的字段为0即可(汇编中写入的2字节对应长度字段及相邻的终止符位置),不需要清空整个SSO缓冲区——因为空字符串根本不会用到缓冲区的内容,完全可以保留原内存的垃圾数据,不影响任何逻辑。
需要注意的是,这是libc++特有的实现差异,其他STL(比如libstdc++)的处理逻辑可能不同,不一定会出现这种性能差异。另外,这种操作本身的耗时极短,在绝大多数实际场景中,两者的性能差异可以忽略不计。
内容的提问来源于stack exchange,提问作者Jan Schultke
相关产品推荐
相关产品推荐

