第4篇:C++ 高效的string_view

string对象的性能问题

了解string对象的内存分配行为后,接下来我们如何考虑使用什么方法来避免字符串频繁的拷贝,有些经验的“老油条”应该都领略过了const string&这类参数类型声明并不能从根本上解决问题(上一篇文章的程序输出已经隐藏地说明了这一点),因为按引用传参仅能避免了参数传递的字符串拷贝,但在被调用函数内部,只要涉及string对象赋值操作,string内部仍然执行拷贝依然存在,特别是大字符串的赋值操作会触发堆内存分配,我们知道堆内存管理是一个高时间成本消耗的操作。

C++的string对象,如果大于默认的字符串长度阀值。对于长度为N的字符串,时间成本为O(n),空间成本是2xS(n);

于是C++17就有了string_view这个标准库的扩展,这个扩展极大地解决了string拷贝的空间成本和时间成本问题。我们本篇要介绍的是string_view是C++程序猿在处理字符串操作的一大福音。因为string_view基本没有涉及内存的额外分配。

#include 
#include 
#include 

void* operator new(std::size_t count){
  std::cout<<"分配了堆内存"<

程序输出:


到这里我们从上图程序输出可以发现,string_view对象从初始化到打印几次调用show_stv()函数都无法涉及触发new操作,并且因为string_view实际上不持有字符串副本,因此string_view从空间成本和时间成本远远胜于string对象。

因为string_view内部的私有数据成员_M_str是一个类似C版本的char*指针,该私有数据成员指向初始化string_view构造函数的字符串副本的地址。我们向被调用函数传递string_view类型的参数,你可以不科学d地因为认为如下类似的代码是相当的

show_stv(std::string_view)

效果相当于

show_stv(char*)

因为它们涉及赋值操作的时间成本是O(1),另外,string_view内部并不持有一个字符串副本 ,所以涉及空间消耗可以认为S(1).

string_view的适用场合

由于string_view对象无法被使用它的函数修改,因此要更新string_view所引用的字符串副本,还是需要修改它所引用的string类型的内部字符串副本。

  • 字符串查找
  • 遍历字符串
  • 显示字符串

结语

我这里并不打算罗列一大堆string_view的api,因为没必要,你要掌握它的基本用法,只要熟悉string对象,掌握string_view自然不是问题。你也可以参考其他相关的文章。

你可能感兴趣的:(第4篇:C++ 高效的string_view)