std :: string_view到底比const std :: string& amp;快多少? [英] How exactly is std::string_view faster than const std::string&?

查看:164
本文介绍了std :: string_view到底比const std :: string& amp;快多少?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

std :: string_view 已进入C ++ 17,因此广泛建议使用它代替 const std :: string&



原因之一就是性能。



有人可以解释准确 std :: string_view如何用作/将比用作参数类型的 const std :: string& 快吗? (假设未在被调用方中进行任何复制)

解决方案

std :: string_view 在某些情况下会更快。



首先, std :: string const& 要求数据位于 std :: string 中,而不是原始的C数组中,由C API返回的 char const * ,由反序列化引擎生成的 std :: vector< char> 等。避免的格式转换避免了复制字节,并且(如果字符串比SBO¹长,特殊的 std :: string 实现)避免了内存分配。

  void foo(std :: string_view bob){
std :: cout<<鲍勃<< \n;
}
int main(int argc,char const * const * argv){
foo(这是一个足以避免std :: string SBO的字符串);
if(argc> 1)
foo(argv [1]);
}

string_view 的情况,但是如果 foo 接受了 std :: string const& 而不是 string_view



第二个真正的大原因是它允许在没有副本的情况下使用子字符串。假设您正在解析2 GB的json字符串(!)²。如果将其解析为 std :: string ,则每个这样的解析节点将在其中存储节点名称或值的副本中的原始数据。 2 gb字符串到本地节点。



相反,如果将其解析为 std :: string_view s,节点引用到原始数据。这样可以节省数百万的分配,并在解析过程中减少一半的内存需求。



您可以获得的加速速度简直是荒谬的。



这是一个极端的情况,但是其他获得子字符串并使用它的情况也可以通过 string_view 产生不错的加速效果。



该决定的重要部分是使用 std :: string_view 会导致的损失。



您丢失了隐式空终止,仅此而已。因此,如果将相同的字符串传递给3个都需要一个空终止符的函数,那么一次转换为 std :: string 可能是明智的。因此,如果已知您的代码需要空终止符,并且您不希望从C样式的源缓冲区等获得字符串,则可以使用 std :: string const& 。否则,请使用 std :: string_view



如果 std :: string_view 有一个标志,说明如果该标志以null结尾(或更奇特的事物),它将删除使用 std :: string const& 的最后一个原因。 / p>

在某些情况下,使用 std :: string 而没有 const& std :: string_view 最佳。如果您需要在调用后无限期拥有该字符串的副本,那么按值取值比较有效。您将处于SBO情况(无需分配,只需复制几个字符即可),或者就可以移动将堆分配的缓冲区移动到本地的 std :: string 。具有两个重载 std :: string&& std :: string_view 可能更快,但仅略有提高,并且






¹小缓冲区优化

p>

²实际用例。


std::string_view has made it to C++17 and it is widely recommended to use it instead of const std::string&.

One of the reasons is performance.

Can someone explain how exactly std::string_view is/will be faster than const std::string& when used as a parameter type? (let's assume no copies in the callee are made)

解决方案

std::string_view is faster in a few cases.

First, std::string const& requires the data to be in a std::string, and not a raw C array, a char const* returned by a C API, a std::vector<char> produced by some deserialization engine, etc. The avoided format conversion avoids copying bytes, and (if the string is longer than the SBO¹ for the particular std::string implementation) avoids a memory allocation.

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] );
}

No allocations are done in the string_view case, but there would be if foo took a std::string const& instead of a string_view.

The second really big reason is that it permits working with substrings without a copy. Suppose you are parsing a 2 gigabyte json string (!)². If you parse it into std::string, each such parse node where they store the name or value of a node copies the original data from the 2 gb string to a local node.

Instead, if you parse it to std::string_views, the nodes refer to the original data. This can save millions of allocations and halve memory requirements during parsing.

The speedup you can get is simply ridiculous.

This is an extreme case, but other "get a substring and work with it" cases can also generate decent speedups with string_view.

An important part to the decision is what you lose by using std::string_view. It isn't much, but it is something.

You lose implicit null termination, and that is about it. So if the same string will be passed to 3 functions all of which require a null terminator, converting to std::string once may be wise. Thus if your code is known to need a null terminator, and you don't expect strings fed from C-style sourced buffers or the like, maybe take a std::string const&. Otherwise take a std::string_view.

If std::string_view had a flag that stated if it was null terminated (or something fancier) it would remove even that last reason to use a std::string const&.

There is a case where taking a std::string with no const& is optimal over a std::string_view. If you need to own a copy of the string indefinitely after the call, taking by-value is efficient. You'll either be in the SBO case (and no allocations, just a few character copies to duplicate it), or you'll be able to move the heap-allocated buffer into a local std::string. Having two overloads std::string&& and std::string_view might be faster, but only marginally, and it would cause modest code bloat (which could cost you all of the speed gains).


¹ Small Buffer Optimization

² Actual use case.

这篇关于std :: string_view到底比const std :: string&amp; amp;快多少?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆