c++ 17提供了一个新的性能工具std::string_view。它有着类似std::string的接口易于使用,但是又不拥有字符串的内存,避免了很多拷贝内存操作,性能接近原始c字符串指针。
char text[]{"hello"};
std::string str{text};
std::string more{str};
std::string_view svtext{"hello"};
std::string_view svstr{svtext};
std::string_view svmore{svstr};
如上代码:
- 第1行,"hello"在可执行文件的二进制中存在一份,在text字符串数组中存在一份
- 第2行,std::string拷贝了一份
- 第3行,std::string拷贝了一份
- 第5行,在可执行文件的二进制中存在一份
因为std::string_view不拥有内存,避免了很多次内存数据拷贝。
其实std::string_view本身很简单,它只有两个成员变量,指向内存的指针和可以访问到的长度。它对它指向的内存是只读的,std::string_view的任何方法都不会改变执行的内存。
std::string raw("Peach");
std::string_view str{ raw };
std::cout << str << std::endl;
str.remove_prefix(1);
std::cout << str << std::endl;
str.remove_suffix(2);
std::cout << str << std::endl;
std::cout << raw << std::endl;
输出:
Peach
each
ea
Peach
同样,如果执行的内存本身自己改变了,就能里面反应到std::string_view里面,如下所示:
char arr[]{ "Gold" };
std::string_view str{ arr };
std::cout << str << '\n'; // Gold
// Change 'd' to 'f' in arr
arr[3] = 'f';
std::cout << str << '\n'; // Golf
输出:
Gold
Golf
此外,std::string_view还能与非null-terminated 字符串配合使用:
// No null-terminator.
char vowels[]{'a', 'e', 'i', 'o', 'u'};
// vowels isn't null-terminated. We need to pass the length manually.
// Because vowels is an array, we can use std::size to get its length.
std::string_view str{vowels, std::size(vowels)};
// This is safe. std::cout knows how to print std::string_views.
std::cout << str << std::endl;
std::string_view并不拥有所观察的字符串的内存,因此需要对内存多加小心:
std::string_view AskForName() {
std::cout << "What's your name?\n";
std::string str{};
std::cin >> str;
std::string_view view{str};
std::cout << "Hello " << view << '\n';
return view;
}
int main() {
std::cout << AskForName() << std::endl;
return 0;
}
上面代码返回了view,但是view所观察的局部变量str离开函数就销毁了,继续使用view会导致未定义的行为。
std::string_view对应的是string,std::string_view背后是basic_string_view模板,因此它有几种字符串变种:
std::string_view std::basic_string_view<char>
std::u8string_view std::basic_string_view<char8_t> (C++20)
std::u16string_view std::basic_string_view<char16_t>
std::u32string_view std::basic_string_view<char32_t>
std::wstring_view std::basic_string_view<wchar_t>
下面是网上有人对比string_view和string性能,看起string_view性能还是有很大提升的,因此我们尽可能多的场合去使用string_view。

参考: