C++17 Optimize program performance by using std::string_view to avoid string copying

  • 2020-11-25 07:23:56
  • OfStack

C++ std::string is a class that is often used in daily Coding. It is very convenient to use, but it also has some disadvantages.

In the following code, the process of parameter passing occurs memory allocation (Memory Allocation) and memory copy.


void fun(const std::string& s) {
  std::cout << s << std::endl;
}

const char* ch = "hello world";

// bad way, expensive if the string is long
fun(ch); 

Consider the following common string interception implementation:


// very long string
std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; 

// bad way, expensive if the string is long
std::cout << str.substr(15, 10) << '\n';

In order to advance the performance of the squeeze program, these expensive string memory allocation and copy operations need to be removed. std::string_view is provided in C++17 to help us achieve this function. The class does not hold a copy of the string, but instead shares its memory space with the source string.

string_view constructor


constexpr basic_string_view() noexcept; (since C++17)
constexpr basic_string_view(const basic_string_view& other) noexcept = default; (since C++17)
constexpr basic_string_view(const CharT* s, size_type count) ; (since C++17)
constexpr basic_string_view(const CharT* s); (since C++17)
template<class It, class End>

Although the std::string_view function with arguments of std::string is not defined, the following code can still be compiled.


std::string str("hello string view!");
std::string_view sview(str);

Because the std::string class overloads the conversion operator for std::string to std::string_view.


operator basic_string_view<charT, traits>() const noexcept;

std::string_view Avoid memory copying

With string_view, we can solve the problem mentioned at the beginning of this article.


void fun(const std::string_view& s) {
  std::cout << s << std::endl;
}

const char* ch = "hello world, char";
fun(ch); 

const std::string str = "hello world, string";
fun(str);

fun({ch, 5});

With std::string_view, there is no need to copy the memory source string for the function arguments either the string array pointer or std::string.


// very long string
std::string str = "lllloooonnnngggg sssstttrrriiinnnggg";

//Good way - No copies are created!
std::string_view view = str;

// string_view::substr returns a new string_view
std::cout << view.substr(15, 10) << '\n';

Similarly, the substr() function of the string does not need to be copied, which can improve the performance of the program for very long strings.

std::string_view

Since std::string_view does not hold the string's memory, its life cycle 1 must be longer than the life cycle of the source string. 1 Some typical examples of lifecycle management errors:


std::string_view sv = std::string("hello world");

std::string_view fun() {
 std::string str("hello world");
 return std::string_view(str);
}

std::string_view does not end with the \0 terminator, so pay attention to the boundary when printing std::string_view, as follows:


#include <iostream>
#include <vector>
#include <string>
#include <string_view>

int main() {
  const char* ch = "hello world";
  
  std::string_view sv(ch, 2);
  
  std::cout << sv << std::endl;
  
  std::cout << sv.data() << std::endl;
  
  return 0;
}

Program output:


he
hello world

std::cout < < sv.data() < < std::endl; This line outputs hello world, because sv still points to the source string memory. When calling sv.data () to print, the convention of C++ for strings is still followed, and the printing does not end until an end character \0 is encountered, at which point the full source string content is output. Of course, this is obviously not as expected, especially when std::string_view points to a string without the \0 terminus, and the program is prone to potential memory problems. So you have to be careful here.

Reference material

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

The above is C++17 using std::string_view to avoid string copy optimization program performance details, more information about c+ 17 std::string_view please pay attention to other related articles on this site!


Related articles: