从文本文件中提取某些行的最有效方法
Most efficient way to extract certain lines from a text file
我有一个可变长度的日志文件,可能包含也可能不包含我正在寻找的字符串。
行有时间戳etc,后面跟着<参数> # & lt;value>我想检查参数并提取值。参数>
下面的实现工作,但我相信一定有一个更有效的方法来解析文件。
重点:
- 大多数行将被忽略
- 大约有1600个日志文件,大小在1 - 20 Mb之间
- 即使每个文件的增益很小也会有优势
NB。parse函数调用substring,然后将其转换为int
如有任何想法,不胜感激
ifstream fileReader(logfile.c_str());
string lineIn;
if(fileReader.is_open())
{
while(fileReader.good())
{
getline(fileReader,lineIn);
if(lineIn.find("value1#") != string::npos)
{
parseValue1(lineIn);
}
else if(lineIn.find("value2#") != string::npos)
{
parseValue2(lineIn);
}
else if(lineIn.find("value3#") != string::npos)
{
parseValue3(lineIn);
}
}
}
fileReader.close();
首先你做的循环是错误的。你的代码应该是:
while( getline( fileReader,lineIn ) ) {
}
其次,行:
if( fileReader.is_open() )
和
fileReader.close();
是多余的。至于速度。我建议使用正则表达式:
std::regex reg ( "(value1#)|(value#2)|(value#3)(\d+)" );
while( getline( fileReader,lineIn ) ) {
std::smatch m;
if( std::regex_search( lineIn.begin(), lineIn.end(), m, reg ) ) {
std::cout << "found: " << m[4] << std::endl;
}
}
当然你需要相应地修改正则表达式。
不幸的是,iostreams非常慢。如果你不能获得足够的性能,你可以考虑用FILE *或mmap代替fstream。
看起来在同一个字符串中有很多重复的搜索,这将不是很有效。
以正确的方式解析文件/行。
在Boost中有三个库可能会有所帮助。
使用正则表达式解析该行:http://www.boost.org/doc/libs/1_53_0/libs/regex/doc/html/index.html
使用标记器http://www.boost.org/doc/libs/1_53_0/libs/tokenizer/index.html
对于完全定制,您可以始终使用Spirit。http://www.boost.org/doc/libs/1_53_0/libs/spirit/doc/html/index.html
第一步是计算在if(lineIn.find(...)...
中花费了多少时间以及实际读取了多少输入文件。
Time应用程序运行的时间(您可能希望选择一些日志文件,而不是所有日志文件)。您可能希望连续运行此操作几次,以确保获得相同(近似)的值。
add:
#if 0
if (lineIn.find(...) ...)
...
#endif
并比较它所花费的时间。我猜这不会有太大的区别。但是,如果搜索是时间的主要组成部分,那么您可能会发现使用更聪明的搜索方法是有益的。有一些非常聪明的方法可以在更大的字符串中搜索字符串。
我将在其他地方发布一些"更快地读取文件"的基准测试。但请记住,您正在读取的硬盘将是主要的时间量。引用:读取文件时
getline vs读取整个文件然后根据换行符
进行分割不太相关,但可能很有趣:
在c++中从文本文件中读取以行分隔的数百万个整数的最有效方法是什么
您的执行瓶颈将在文件I/o上。
我建议您在一次取出中将尽可能多的数据放入缓冲区。接下来,在缓冲区中搜索令牌。
为了搜索它,你必须阅读文本,所以你最好尽可能多地阅读文件。
在内存中读取过多的数据可能会有一些缺点。如果操作系统无法容纳所有的数据,它可能会将其分页到硬盘驱动器,这使得该技术毫无价值(除非您希望操作系统以块方式处理读取文件)。
一旦文件在内存中,搜索技术的性能提升可以忽略不计。
- 在C++中初始化向量映射的最有效方法
- 将此布尔值传递给此函数的最有效方法是什么?
- 比较C++变量的最有效方法
- 在 c++ 中解决段树以外的范围查询的有效方法是什么?
- 存储变量的更有效方法是什么?
- 确保套装新鲜度的有效方法
- 当映射包含字符串向量作为值时,从值中获取键的有效方法
- 映射唯一值和重复值的有效方法.可以访问键或值的位置
- 在C++事务之间存储大量字符数据的有效方法
- 在unordered_multimap中精确迭代一次每个键的有效方法
- 一种将 Dart 中的字节数据转换为 C++ 中的无符号字符*的有效方法?
- 检查两个向量是否并行的最有效方法
- 从浮点数中删除小数部分但保留类型的有效方法
- 传递非泛型函数的最有效方法是什么?
- 按升序打印矢量的所有元素直到它为空而没有重复项的最有效方法是什么?
- 创建字符串数组的有效方法
- 返回一个引用C++中另一个类对象的对象的有效方法
- C++去除前x个元素的有效方法,在不改变向量大小的情况下将第x+1个元素推到第一个
- 将一种数据类型的向量复制到同一数据类型的结构向量中的有效方法是什么
- 从std::map值中获取密钥的有效方法