繁体   English   中英

从文本文件中提取某些行的最有效方法

[英]Most efficient way to extract certain lines from a text file

我有一个可变长度的日志文件,该文件可能包含也可能不包含我要查找的字符串。

行有时间戳等,后跟<参数>#<值>,我想检查参数并提取值。

下面的实现有效,但是我确定必须有一种更有效的方法来解析文件。

关键点:

  • 大多数行将被忽略
  • 大约有1600个1-20 Mb的日志文件
  • 每个文件即使很小的收益也将是一个优势

注意 parse函数调用子字符串,然后将其转换为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;
    } 
}

当然,您将需要相应地修改正则表达式。

不幸的是,众所周知,iostream速度很慢。 如果您无法获得足够的性能,则可以考虑用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(...)...花费了多少时间,以及实际读取输入文件的时间是多少。

应用程序运行所花费的时间(您可能希望选择一系列日志文件,而不是全部日志文件)。 您可能希望连续运行几次以查看得到的值(大约)相同。

添加:

#if 0
if (lineIn.find(...) ...) 
...
#endif

并比较所需的时间。 我的猜测是,它实际上并不会带来太大的改变。 但是,如果搜索是当前的主要组成部分,则可能会发现使用更聪明的搜索方法会有所帮助。 有一些非常聪明的方法可以搜索较大的字符串中的字符串。

我将发布一些其他地方发布的“更快阅读文件”基准。 但是请记住,正在读取的硬盘将占用大量时间。

参考文献:

读取文件时读取getline与读取整个文件然后根据换行符拆分

不太相关,但也许有趣:

从C ++中的文本文件中读取以行分隔的数百万个整数的最佳有效方法是什么

您的执行瓶颈将在文件I / O中。
我建议您一次提取尽可能多的数据到缓冲区中。 接下来,在缓冲区中搜索您的令牌。

您必须阅读文本才能进行搜索,因此您最好尽可能多地阅读文件。

将过多的数据读取到内存中可能会有一些缺点。 如果操作系统无法容纳所有数据,则可能会将其分页到硬盘驱动器中,这将使该技术毫无价值(除非您希望操作系统处理分块读取文件的操作)。

一旦文件存储在内存中,搜索技术的性能提升就可以忽略不计。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM