std::string_view 到底比 const std::string& 快多少?

2024-01-15

std::string_view http://en.cppreference.com/w/cpp/string/basic_string_view已经发展到 C++17 并被广泛推荐使用它来代替const std::string&.

原因之一是性能。

有人可以解释一下如何exactly std::string_view是/将会比const std::string&什么时候用作参数类型? (假设被调用者没有复制)


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 小缓冲区优化

² 实际用例。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

std::string_view 到底比 const std::string& 快多少? 的相关文章

随机推荐