std::string_view
在某些情况下更快。
First, std::string const&
要求数据位于std::string
,而不是原始 C 数组,char const*
由 C API 返回,std::vector<char>
由某些反序列化引擎等生成。避免的格式转换避免了复制字节,并且(如果字符串比特定的 SBO1 长)std::string
实现)避免了内存分配。
void foo( std::string_view bob ) {
std::cout << bob << "\n";
}
int main(int argc, char const*const* argv) {
foo( "This is a string long enough to avoid the std::string SBO" );
if (argc > 1)
foo( argv[1] );
}
没有进行任何分配string_view
情况,但会有如果foo
took a std::string const&
代替string_view
.
第二个真正重要的原因是它允许在没有副本的情况下使用子字符串。假设您正在解析一个 2 GB 的 json 字符串 (!)²。如果你把它解析成std::string
,每个这样的解析节点,它们存储节点的名称或值copies将原始数据从 2 GB 字符串传输到本地节点。
相反,如果你将其解析为std::string_view
是,节点refer到原始数据。这可以节省数百万次分配并将解析期间的内存需求减半。
你可以获得的加速简直是荒谬的。
这是一个极端的情况,但其他“获取子字符串并使用它”的情况也可以产生不错的加速string_view
.
做出决定的一个重要部分是您因使用而失去的东西std::string_view
。虽然不多,但确实是一些东西。
你失去了隐式空终止,仅此而已。因此,如果相同的字符串将传递给 3 个函数,所有这些函数都需要 null 终止符,则转换为std::string
一次可能是明智的。因此,如果已知您的代码需要空终止符,并且您不希望从 C 样式源缓冲区等提供字符串,则可能需要std::string const&
。否则采取std::string_view
.
If std::string_view
有一个标志,表明如果它是空终止的(或者更奇特的东西),它甚至会删除最后一个使用 a 的原因std::string const&
.
有一种情况需要采取std::string
没有const&
是最优的std::string_view
。如果您需要在调用后无限期地拥有字符串的副本,则按值获取是有效的。您要么处于 SBO 情况(并且没有分配,只需几个字符副本来复制它),要么您将能够move将堆分配的缓冲区放入本地std::string
。有两个重载std::string&&
and std::string_view
可能会更快,但只是有限的,并且会导致适度的代码膨胀(这可能会让您失去所有的速度增益)。
1 小缓冲区优化
² 实际用例。