为什么ifstream :: read比使用迭代器快得多?

时间:2015-04-20 21:25:34

标签: c++ performance optimization io iterator

实际上,有很多方法可以将文件读入字符串。 两个常见的是使用ifstream :: read直接读取字符串并使用steambuf_iterators和std :: copy_n:

使用ifstream :: read:

std::ifstream in {"./filename.txt"};
std::string contents;
in.seekg(0, in.end);
contents.resize(in.tellg());
in.seekg(0, in.beg);
in.read(&contents[0], contents.size());

使用std :: copy_n:

std::ifstream in {"./filename.txt"};
std::string contents;
in.seekg(0, in.end);
contents.resize(in.tellg());
in.seekg(0, in.beg);
std::copy_n(std::streambuf_iterator<char>(in), 
            contents.size(), 
            contents.begin();

许多基准测试表明,第一种方法比第二种方法快得多(在我的机器中使用g ++ - 4.9,使用-O2和-O3标志时速度提高了约10倍)我想知道可能是什么原因造成的这种性能差异。

1 个答案:

答案 0 :(得分:2)

read是单个iostream设置(每个iostream操作的一部分)和对OS的单个调用,直接读入您提供的缓冲区。

迭代器通过使用char重复提取单个operator>>来工作。由于缓冲区大小,这可能意味着更多的OS调用,但更重要的是它还意味着重复设置和拆除iostream哨兵,这可能意味着互斥锁,并且通常意味着一堆其他东西。此外,operator>>是一种格式化操作,而read是未格式化的,这是每次操作的额外设置开销。

编辑:疲惫的眼睛看到istream_iterator而不是istreambuf_iterator。当然istreambuf_iterator不做格式化输入。它在streambuf上调用sbumpc或类似的东西。仍然有很多调用,并且使用缓冲区,这可能比整个文件小。