C++17 使用 std::string_view避免字符串拷貝優(yōu)化程序性能
C++中std::string是日常Coding中經(jīng)常使用的一個(gè)類(lèi),使用起來(lái)非常方便,但是也存在一些弊端。
如下代碼,參數(shù)傳遞的過(guò)程發(fā)生了內(nèi)存分配(Memory Allocation)和內(nèi)存拷貝。
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);
再看下面的常用的字符串截取實(shí)現(xiàn):
// very long string std::string str = "lllloooonnnngggg sssstttrrriiinnnggg"; // bad way, expensive if the string is long std::cout << str.substr(15, 10) << '\n';
為了進(jìn)一步的壓榨程序的性能,需要移除掉這些昂貴的字符串內(nèi)存分配和拷貝操作。C++17中提供了std::string_view可以幫助我們實(shí)現(xiàn)這一功能,該類(lèi)并不持有字符串的拷貝,而是與源字符串共享其內(nèi)存空間。
string_view構(gòu)造函數(shù)
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>
雖然沒(méi)有定義參數(shù)為std::string的std::string_view函數(shù),下面的代碼仍然可以通過(guò)編譯。
std::string str("hello string view!");
std::string_view sview(str);
因?yàn)閟td::string類(lèi)重載了std::string到std::string_view的轉(zhuǎn)換操作符。
operator basic_string_view<charT, traits>() const noexcept;
std::string_view避免內(nèi)存拷貝
有了string_view,我們就可以很好的解決文章開(kāi)頭提到的問(wèn)題。
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});
有了std::string_view,函數(shù)參數(shù)不管是字符串?dāng)?shù)組指針,還是std::string,都不需要拷貝內(nèi)存源字符串。
// 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';
同理,字符串的substr()函數(shù)也不需要再進(jìn)行拷貝了,這對(duì)于非常長(zhǎng)的字符串,可以有效的提升程序的性能表現(xiàn)。
std::string_view注意事項(xiàng)
由于std::string_view并不持有字符串的內(nèi)存,所以它的生命周期一定要比源字符串的生命周期長(zhǎng)。一些典型的生命周期管理錯(cuò)誤的例子:
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的結(jié)尾并沒(méi)有\(zhòng)0結(jié)束符,所以在輸出std::string_view的時(shí)候要注意邊界,如下代碼:
#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;
}
程序輸出:
he hello world
std::cout << sv.data() << std::endl; 這行代碼輸出了hello world,這是因?yàn)閟v仍然指向源字符串內(nèi)存,調(diào)用sv.data()打印時(shí),仍然沿用了C++對(duì)于字符串的約定,直到遇到結(jié)束符\0時(shí),打印才結(jié)束,這時(shí)候就輸出了完整的源字符串內(nèi)容。當(dāng)然這里明顯是不符合預(yù)期的,尤其是std::string_view指向的字符串沒(méi)有\(zhòng)0結(jié)束符的時(shí)候,程序很容易出現(xiàn)潛在的內(nèi)存問(wèn)題。所以此處一定要小心。
參考材料
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避免字符串拷貝優(yōu)化程序性能的詳細(xì)內(nèi)容,更多關(guān)于c++17 std::string_view的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- 利用C++實(shí)現(xiàn)從std::string類(lèi)型到bool型的轉(zhuǎn)換
- C/C++中關(guān)于std::string的compare陷阱示例詳解
- C++ float轉(zhuǎn)std::string 小數(shù)位數(shù)控制問(wèn)題
- C++中std::string::npos的用法
- C++17中std::string_view的使用
- C++面試八股文之std::string實(shí)現(xiàn)方法
- C++中std::stringstream多類(lèi)型數(shù)據(jù)拼接和提取用法小結(jié)
- c++使用 std::string 存儲(chǔ)二進(jìn)制數(shù)據(jù)
相關(guān)文章
C語(yǔ)言實(shí)現(xiàn)簡(jiǎn)單的三子棋游戲
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)三子棋游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-09-09
C語(yǔ)言示例講解do?while循環(huán)語(yǔ)句的用法
在不少實(shí)際問(wèn)題中有許多具有規(guī)律性的重復(fù)操作,因此在程序中就需要重復(fù)執(zhí)行某些語(yǔ)句。一組被重復(fù)執(zhí)行的語(yǔ)句稱(chēng)之為循環(huán)體,能否繼續(xù)重復(fù),決定循環(huán)的終止條件2022-06-06
C語(yǔ)言實(shí)現(xiàn)文件讀寫(xiě)操作
這篇文章主要為大家詳細(xì)介紹了C語(yǔ)言實(shí)現(xiàn)文件讀寫(xiě)操作,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-12-12
C++中關(guān)于Crt的內(nèi)存泄漏檢測(cè)的分析介紹
本篇文章介紹了,在C++中關(guān)于Crt的內(nèi)存泄漏檢測(cè)的分析說(shuō)明。需要的朋友參考下2013-04-04
C語(yǔ)言實(shí)現(xiàn)天氣信息管理系統(tǒng)
這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)天氣信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2020-06-06
C++之CNoTrackObject類(lèi)和new delete操作符的重載實(shí)例
這篇文章主要介紹了C++之CNoTrackObject類(lèi)和new delete操作符的重載實(shí)例,是C++程序設(shè)計(jì)中比較重要的概念,需要的朋友可以參考下2014-10-10

