C++17 使用 std::string_view避免字符串拷贝优化程序性能
C++中std::string是日常Coding中经常使用的一个类,使用起来非常方便,但是也存在一些弊端。
如下代码,参数传递的过程发生了内存分配(MemoryAllocation)和内存拷贝。
voidfun(conststd::string&s){ std::cout<再看下面的常用的字符串截取实现:
//verylongstring std::stringstr="lllloooonnnnggggsssstttrrriiinnnggg"; //badway,expensiveifthestringislong std::cout<为了进一步的压榨程序的性能,需要移除掉这些昂贵的字符串内存分配和拷贝操作。C++17中提供了std::string_view可以帮助我们实现这一功能,该类并不持有字符串的拷贝,而是与源字符串共享其内存空间。
string_view构造函数
constexprbasic_string_view()noexcept;(sinceC++17) constexprbasic_string_view(constbasic_string_view&other)noexcept=default;(sinceC++17) constexprbasic_string_view(constCharT*s,size_typecount);(sinceC++17) constexprbasic_string_view(constCharT*s);(sinceC++17) template虽然没有定义参数为std::string的std::string_view函数,下面的代码仍然可以通过编译。
std::stringstr("hellostringview!"); std::string_viewsview(str);因为std::string类重载了std::string到std::string_view的转换操作符。
operatorbasic_string_view()constnoexcept; std::string_view避免内存拷贝
有了string_view,我们就可以很好的解决文章开头提到的问题。
voidfun(conststd::string_view&s){ std::cout<有了std::string_view,函数参数不管是字符串数组指针,还是std::string,都不需要拷贝内存源字符串。
//verylongstring std::stringstr="lllloooonnnnggggsssstttrrriiinnnggg"; //Goodway-Nocopiesarecreated! std::string_viewview=str; //string_view::substrreturnsanewstring_view std::cout<同理,字符串的substr()函数也不需要再进行拷贝了,这对于非常长的字符串,可以有效的提升程序的性能表现。
std::string_view注意事项
由于std::string_view并不持有字符串的内存,所以它的生命周期一定要比源字符串的生命周期长。一些典型的生命周期管理错误的例子:
std::string_viewsv=std::string("helloworld"); std::string_viewfun(){ std::stringstr("helloworld"); returnstd::string_view(str); }std::string_view的结尾并没有\0结束符,所以在输出std::string_view的时候要注意边界,如下代码:
#include#include #include #include intmain(){ constchar*ch="helloworld"; std::string_viewsv(ch,2); std::cout< 程序输出:
he helloworldstd::cout<
参考材料
https://riptutorial.com/cplusplus/example/6571/using-the-std–string-view-class
https://en.cppreference.com/w/cpp/string/basic_string_view
https://segmentfault.com/a/1190000018387368
以上就是C++17使用std::string_view避免字符串拷贝优化程序性能的详细内容,更多关于c++17std::string_view的资料请关注毛票票其它相关文章!