改进c++中ifstream的性能

Improving performance of ifstream in c++

本文关键字:性能 ifstream c++ 改进      更新时间:2023-10-16

我很抱歉如果这个问题有点模糊或只是简单的愚蠢,我仍然是一个非常新手。

我需要从c++的web日志文件中提取信息。字符串操作是相对的,而以及时的方式访问数据则不是。我正在做什么

string str;

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

while (getline(fh,str));

从这里我从字符串中得到有用的数据。这对于包含100个条目的日志文件来说工作得很好,但是对于包含数百万个以上条目的日志文件来说就太长了。如有任何帮助,不胜感激

我真的怀疑I/O对您的伤害比ifstream更大。你检查过你的CPU是否被限制了吗?很可能是磁盘和缓存局部性问题。

在这种情况下,你可能无能为力。

如果是CPU限制,你是否分析了CPU时间的去向?

在浪费了很多时间之后,我在Quincy2005而不是Microsoft Visual studio中编译了相同的代码。结果是戏剧性的。从40分钟的执行时间到1分钟。在Microsoft Visual Studio中,通过将文件处理程序的指针传递给getline函数,可以实现一些改进。在基于Linux的系统上,执行大约需要40秒。我骂了微软整整40分钟,说它浪费了我的时间。

这里是我发现提取文件的最快方法:

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());

然而,如果你的文件真的那么大,我强烈建议你把它作为一个流来操作…

@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");
}