为什么ostringstream比ofstream更快

时间:2011-03-04 10:01:13

标签: c++ filestream iostream

要将多个数据写入文件,我有两种方法:

  1. 直接逐一写入.stream

    ofstream file("c:\\test.txt");
    for (int i = 0; i < 10000; ++i)
    {
        file << data[i];
    }
    
  2. 首先写入istringstream,然后立即写入ofstream

    ostringstream strstream;
    for (int i = 0; i < 10000; ++i)
    {
        strstream << data[i];
    }
    ofstream file("c:\\test.txt");
    file << strstream.str();
    
  3. 毫不奇怪,第二种方法更快,实际上,它比HP7800机器上的第一种方法快4倍。

    但为什么呢?我知道ofstream正在使用filebuf,而ostringstream正在使用stringbuf - 作为缓冲区,它们都应该驻留在内存中,因此应该没有区别。

    引擎盖下的区别是什么?

3 个答案:

答案 0 :(得分:15)

您是否经常使用std::endl代替'\n'std::endl执行两项操作:将'\n'插入流中,然后 将缓冲区刷新到磁盘 。我已经看到代码通过这样做而谈到严重的性能损失。 (在修复之后,代码运行速度提高了5-10倍。)
刷新到字符串缓冲区将比刷新到磁盘快得多,这样就可以解释您的发现。

如果情况并非如此,您可能会考虑增加缓冲区大小:

const std::size_t buf_size = 32768;
char my_buffer[buf_size];
ofstream file("c:\\test.txt");
file.rdbuf()->pubsetbuf(my_buffer, buf_size);

for (int i = 0; i < 10000; ++i)
{
    file << data[i];
}

答案 1 :(得分:4)

磁盘很慢。许多小写都比一大写更贵。

答案 2 :(得分:2)

它可能是特定操作系统的实现问题。 另外我猜想ofstream缓冲区(buflen)小于10000,其典型值是4095.所以尝试运行i&lt; 4096并且响应时间应该完全相同!

在第二种情况下它更快的原因:

在第一种情况下,当缓冲区已满(buflen = 4095bytes)时,它将被写入磁盘。因此,对于i <10000,它已经使它被冲洗了3次。

在第二种情况下,所有数据首先在RAM中准备,然后一次刷新到硬盘。所以已经保存了两次冲洗!