字符串拆分效率比对记录
目录
概述
自定义字符串拆分函数,分别处理同样的文本文件(超过百万行)统计各拆分函数的效率。
拆分函数
-
使用regex
std::vector<std::string> SplitString(const std::string& in_str, const std::string& split_flag)
{
std::vector<std::string> result_vec;
try
{
std::regex re{ split_flag };
return std::vector<std::string>{
std::sregex_token_iterator(in_str.begin(), in_str.end(), re, -1),
std::sregex_token_iterator()
};
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
return result_vec;
}
-
使用C函数strtok
vector<string> SplitString2(const string& str, const string& pattern)
{
char* strc = new char[strlen(str.c_str()) + 1];
strcpy(strc, str.c_str()); //string转换成C-string
vector<string> res;
char* temp = strtok(strc, pattern.c_str());
while (temp != NULL)
{
res.push_back(string(temp));
temp = strtok(NULL, pattern.c_str());
}
delete[] strc;
return res;
}
-
使用stringstream
vector<string> SplitString3(const string& str, const char pattern)
{
vector<string> res;
std::stringstream input(str); //读取str到字符串流中
string temp;
//使用getline函数从字符串流中读取,遇到分隔符时停止,和从cin中读取类似
//注意,getline默认是可以读取空格的
while (getline(input, temp, pattern))
{
res.push_back(temp);
}
return res;
}
-
使用string库函数
void SplitString4(const string& str, const string& delimiters,
vector<string>& elems, bool skip_empty = true)
{
string::size_type pos, prev = 0;
while ((pos=str.find_first_of(delimiters,prev))!=string::npos)
{
if (pos > prev) {
if (skip_empty && 1 == pos - prev)
break;
elems.emplace_back(str, prev, pos - prev);
}
prev = pos + 1;
}
if (prev < str.size())
{
elems.emplace_back(str, prev, str.size() - prev);
}
}
结果
-
测试程序
#include <iostream>
#include <string>
#include <vector>
#include <regex>
#include <stdio.h>
#include <sstream>
#include <chrono>
//字符串分离测试
int main() {
std::string in_path{ "D:/01.log" };
std::string out_path{ "D:/Test/" };
FILE* fp = fopen(in_path.c_str(), "r");
if (fp == nullptr) {
printf("无法打开数据文件\n");
return 0;
}
FILE* log_subs = fopen((out_path + "subs.txt").c_str(), "ab+");
if (log_subs == nullptr) {
printf("无法打开数据文件\n");
return 0;
}
char buff_line[1024]; //一行数据
char log_line[1024]; //记录一条数据
auto start_time = std::chrono::steady_clock::now();
while (!feof(fp))
{
try
{
if (!fgets(buff_line, sizeof(buff_line), fp) || strlen(buff_line) == 1)
{
continue;
}
std::vector<string> str_vec;
std::string line_str{ buff_line };
SplitString4(line_str, "\t", str_vec);
str_vec.clear();
//存于log_line中
sprintf(log_line, "%s",
line_str.c_str());
//写入文件
fwrite(log_line, strlen(log_line), 1, log_subs);
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
auto end_time = std::chrono::steady_clock::now();
auto duration_time = std::chrono::duration<double>(end_time - start_time);
std::string out_time = std::to_string(duration_time.count());
std::cout << "解析消耗:" << out_time << std::endl;
printf("解析完成!\n");
}
-
测试结果
时间 | |
SplitString | 15.62s |
SplitString2 | 2.36s |
SplitString3 | 3.05s |
SplitString4 | 1.86s |