c++ 17 vector中string的性能问题 std::vector<std::string> string vs string_view
1,C风格字符串一般以char* 或 char str[]表示,字符串以'\0'结尾
2,sizeof()获得给定数据类型或变量的内存大小,strlen()获得字符串长度
3,字符串字面量
char* arr = "hello"; arr[1] = 'b'; // 未定义行为,非法 char arr[] = "hello"; arr[1] = 'b'; // 可以修改
4,原始字符串字面量
const char* str = R"(hello "world"!)" // 以R"(开头,以)"结尾
5,C++ std::string类
a, 重载了+、[]、==、!=、<、<= 等运算符 b, string类的c_str()方法可以获得一个C风格的const char* c, 高级数值转换与低级数值转换
6. string_view (c++ 17):
a, 无法直接连接一个string和string_view,需要这样:str+sv.data(); b, string_view可以作为参数按值传递给函数,因为其本质是指针和长度,非常高效 c, 无法从string_view隐式构建一个string,要么使用一个显示的string构造函数,要么使用string_view::data(); d, auto sv = "my string_view"sv; // string_view字面量
不错的string介绍:
https://www.cnblogs.com/ranbom/p/12675229.html
vector 转换成 string
edit play_arrow brightness_4 // C++ program transform a vector into // a string. #include <vector> #include <string> #include <algorithm> #include <sstream> #include <iterator> #include <iostream> int main() { std::vector<int> vec; vec.push_back(1); vec.push_back(2); vec.push_back(3); vec.push_back(4); vec.push_back(5); vec.push_back(6); std::ostringstream vts; if (!vec.empty()) { // Convert all but the last element to avoid a trailing "," std::copy(vec.begin(), vec.end()-1, std::ostream_iterator<int>(vts, ", ")); // Now add the last element with no delimiter vts << vec.back(); } std::cout << vts.str() << std::endl; }
https://www.geeksforgeeks.org/transform-vector-string/
c++ string 分配内存重载。可以查看创建string时内存分配情况
// sso.cpp #include <iostream> #include <string> void* operator new(std::size_t count){ std::cout << " " << count << " bytes" << std::endl; return malloc(count); } void getString(const std::string& str){} int main() { std::cout << std::endl; std::cout << "std::string" << std::endl; std::string small = "0123456789"; std::string substr = small.substr(5); std::cout << " " << substr << std::endl; std::cout << std::endl; std::cout << "getString" << std::endl; getString(small); getString("0123456789"); const char message []= "0123456789"; getString(message); std::cout << std::endl; }
对大文件substr性能测试:
// substr.cpp #include <chrono> #include <fstream> #include <iostream> #include <random> #include <sstream> #include <string> #include <vector> #include <string_view> static const int count = 30; static const int access = 10000000; int main(){ std::cout << std::endl; std::ifstream inFile("grimm.txt"); std::stringstream strStream; strStream << inFile.rdbuf(); std::string grimmsTales = strStream.str(); size_t size = grimmsTales.size(); std::cout << "Grimms' Fairy Tales size: " << size << std::endl; std::cout << std::endl; // random values std::random_device seed; std::mt19937 engine(seed()); std::uniform_int_distribution<> uniformDist(0, size - count - 2); std::vector<int> randValues; for (auto i = 0; i < access; ++i) randValues.push_back(uniformDist(engine)); auto start = std::chrono::steady_clock::now(); for (auto i = 0; i < access; ++i ) { grimmsTales.substr(randValues[i], count);//放到vector中时参考下面的性能测试,也许不会性能那么差。 } std::chrono::duration<double> durString= std::chrono::steady_clock::now() - start; std::cout << "std::string::substr: " << durString.count() << " seconds" << std::endl; std::string_view grimmsTalesView{grimmsTales.c_str(), size}; start = std::chrono::steady_clock::now(); for (auto i = 0; i < access; ++i ) { grimmsTalesView.substr(randValues[i], count); } std::chrono::duration<double> durStringView= std::chrono::steady_clock::now() - start; std::cout << "std::string_view::substr: " << durStringView.count() << " seconds" << std::endl; std::cout << std::endl; std::cout << "durString.count()/durStringView.count(): " << durString.count()/durStringView.count() << std::endl; std::cout << std::endl; }
参考:https://www.modernescpp.com/index.php/c-17-avoid-copying-with-std-string-view
性能测试
来自网址:https://quick-bench.com/q/I53xUH8inBWFyLCbZPu3y5jlEyU
用c++ 17的string_view替换实现做测试。
string 在没有优化时慢。单在 o3 优化后,反而更快。
#include <string_view> #include <algorithm> std::vector<std::string> split(const std::string& str, const std::string& delims = " ") { std::vector<std::string> output; auto first = std::cbegin(str); while (first != std::cend(str)) { const auto second = std::find_first_of(first, std::cend(str), std::cbegin(delims), std::cend(delims)); if (first != second) output.emplace_back(first, second); //注意这么没有用substr。性能不会下降???? if (second == std::cend(str)) break; first = std::next(second); } return output; } std::vector<std::string_view> splitSV(std::string_view strv, std::string_view delims = " ") { std::vector<std::string_view> output; size_t first = 0; while (first < strv.size()) { const auto second = strv.find_first_of(delims, first); if (first != second) output.emplace_back(strv.substr(first, second-first)); if (second == std::string_view::npos) break; first = second + 1; } return output; } const std::string_view LoremIpsumStrv{ "Lorem ipsum dolor sit amet, consectetur adipiscing elit," "sed do eiusmod tempor incididuntsuperlongwordsuper ut labore et dolore magna aliqua. Ut enim ad minim veniam, " "quis nostrud exercitation ullamco laboris nisi ut aliquipsuperlongword ex ea commodo consequat. Duis aute" "irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." "Excepteur sint occaecat cupidatatsuperlongword non proident, sunt in culpa qui officia deserunt mollit anim id est laborum." }; static void StringSplit(benchmark::State& state) { std::string str { LoremIpsumStrv }; // Code inside this loop is measured repeatedly for (auto _ : state) { auto v = split(str); benchmark::DoNotOptimize(v); } } // Register the function as a benchmark BENCHMARK(StringSplit); static void StringViewSplit(benchmark::State& state) { for (auto _ : state) { auto v = splitSV(LoremIpsumStrv); benchmark::DoNotOptimize(v); } } BENCHMARK(StringViewSplit);
分类:
C/C++
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2015-11-27 常用安卓开发技巧汇总