将函数入参const std::string&替换为std::string_view是否等价?
结论
二者不等价,在使用场景、运行效率、内存开销、功能支持上都存在明显差异,不存在绝对的优劣,需要结合实际使用场景选择。
运行效率差异
- 传入参数为
std::string类型时:const std::string&是零开销,直接绑定已有对象的引用,无额外操作。std::string_view需要构造一个临时视图对象,开销仅为拷贝指针和长度两个值,几乎可以忽略,但仍比直接绑定引用略高。 - 传入参数为字符串字面量、
const char*、字符数组等非std::string类型时:const std::string&会隐式构造临时std::string对象,长字符串会触发堆内存分配和后续的析构开销,即使是短字符串触发SSO(短字符串优化)也存在对象构造开销。std::string_view直接构造视图即可,无任何内存分配和额外的对象构造开销,性能远高于前者。 - 若需要在函数内部持久化存储入参:
std::string_view仅持有视图不持有数据,需要额外拷贝一份字符串避免悬空;const std::string&可以直接拷贝构造新的std::string,二者在该场景下开销相当,但const std::string&不容易出现悬空误用。
内存消耗差异
const std::string&本身仅占1个指针的大小(64位系统下为8字节),但如果触发隐式临时std::string构造,会额外占用std::string对象本身的开销(64位系统下通常为24字节)加字符串内容的存储空间,短字符串SSO场景下内容存在对象内部,无需额外堆空间。std::string_view本身占2个指针的大小(64位系统下为16字节),无论传入的字符串多长,都不会额外分配内存存储字符串内容,本身仅记录指向原内容的指针和长度。
功能支持差异
const std::string&可以调用所有std::string的const成员方法,c_str()方法返回的指针保证以\0结尾,可以直接传入C风格接口;只要原std::string对象不销毁,引用就始终有效,不容易出现悬空问题。std::string_view没有c_str()方法,data()返回的指针不保证以\0结尾,如果要传入C风格接口必须先构造std::string,否则会触发未定义行为;同时std::string_view不持有数据所有权,生命周期完全依赖原字符串,如果原字符串提前销毁,视图就会变成野指针,非常容易出现误用。- 入参支持范围:
std::string_view支持所有连续字符序列作为入参,包括std::string、const char*、字符串字面量、std::array<char>、字符数组等;const std::string&仅支持可隐式转换为std::string的类型,入参范围更窄。
选型建议
- 若函数内部需要依赖
\0结尾的字符串、或者需要持久化存储入参,优先选择const std::string&。 - 若函数仅对入参做临时只读处理、不需要
\0结尾,优先选择std::string_view,尤其是入参大概率为字符串字面量或const char*的场景,性能提升非常明显。
内容的提问来源于stack exchange,提问作者Zohar81
相关产品推荐
相关产品推荐

