2011-04-18 193 views
4

我很抱歉如果这个问题有点模糊或者很愚蠢,我仍然是一个新手。在C++中改善ifstream的性能

我需要从C++中的Web日志文件中提取信息。字符串操作相对而言,及时访问数据不是。 我目前

string str;

ifstream fh("testlog.log",ios::in);

while (getline(fh,str));

做什么从这里我得到的字符串中的有用数据。这对于具有100个条目的日志文件来说工作良好,但是对于具有百万个条目的日志文件会永远占用。 任何帮助将大大赞赏

+2

只是为了测试,你可以尝试使用'fgets'吗?用'fopen'打开文件,然后用'while(fgets(cstr,256,fp))'来打开文件。告诉我们你的结果是什么(需要多长时间)。 – nc3b 2011-04-18 21:55:09

+0

您是否已通过简介查看瓶颈?如果它是磁盘,代码本身无法解决这个问题。 (如果你的CPU时间不是IO时代的矮小,你可以多线程。) – GManNickG 2011-04-18 22:07:10

回答

1

在这里,我找到解压缩文件的最快方法:

std::ifstream file("test.txt", std::ios::in | std::ios::end); 

std::size_t fileSize = file.tellg(); 

std::vector<char> buffer(fileSize); 

file.seekg(0, std::ios::beg); 

file.read(buffer.data(), fileSize); 

std::string str(buffer.begin(), buffer.end()); 

然而,如果你的文件是真有那么大,我强烈建议你把它处理为流。 ..

+0

好吧,我所做的就是获得文件大小,就像你所做的一样。将值除以2,对于1个动态数组似乎就是对大数。将字符读成字符串似乎一直在浪费。所以我想我可以尝试读取数组中的每一行,而不需要字符串函数的帮助。它看起来有点凌乱 – Jacques 2011-04-19 09:26:00

2

我真的怀疑I/O在这里比在ifstream更伤害你。您是否检查过您是否实际受到CPU限制?很可能你有磁盘和缓存局部性问题。

在这种情况下可能没有太多可以做的事情。

如果它是CPU绑定你有没有分析CPU时间的去向?

1

在浪费了几个小时的时间之后,我在Quincy2005而不是Microsoft Visual Studio中编译了相同的代码。结果是戏剧性的。从40分钟的执行时间到1分钟。通过将文件处理程序的指针传递给getline函数,可以在Microsoft Visual Studio中完成一些改进。在基于Linux的系统上,大约需要40秒才能执行。为了浪费我的时间,我诅咒微软40分钟。

+2

什么是Quincy2005? – 2011-07-15 11:31:11

1

@Errata:

你确定,你的代码会快于说:

std::ifstream in("test.txt"); 
in.unsetf(std::ios::skipws); 
std::string contents; 
std::copy(
     std::istream_iterator<char>(in), 
     std::istream_iterator<char>(), 
     std::back_inserter(contents)); 

此外,OP要面向行访问,这将方便地做到:

std::ifstream in("test.txt"); 
in.unsetf(std::ios::skipws); 
size_t count = std::count_if(
     std::istream_iterator<std::string>(in), 
     std::istream_iterator<std::string>(), 
     &is_interesting); 
std::cout << "Interesting log lines: " << count << std::endl; 

当然定义了一个谓词,例如

static bool is_interesting(const std::string& line) 
{ 
    return std::string::npos != line.find("FATAL"); 
}