std :: ifstream明显慢于FILE吗?

时间:2009-01-25 06:03:15

标签: c++ optimization file-io ifstream

我被告知我的库比它应该慢,大约30+次解析特定文件(文本文件,大小326 kb)太慢。用户建议我可能正在使用std::ifstream(大概是FILE)。

我宁愿不盲目改写,所以我想我先在这里查看,因为我的猜测是其他地方的瓶颈。我正逐字逐句阅读,所以我使用的唯一功能是get()peek()tellg()/seekg()

更新

我描述了,得到了confusing输出 - gprof似乎并没有想到花了这么长时间。我重写了程序,首先将整个文件读入缓冲区,然后加速大约100倍。我认为问题可能是花了很长时间的tellg()/seekg(),但gprof可能由于某种原因无法看到。在任何情况下,ifstream 似乎都会缓冲整个文件,即使是这个大小。

6 个答案:

答案 0 :(得分:25)

我不认为这会有所作为。特别是如果你通过char读取char,I / O的开销可能完全支配任何 else。 为什么一次读取单个字节?你知道这是多么低效吗?

在326kb文件上,最快的解决方案很可能是立即将其读入内存。

std :: ifstream和C等价物之间的区别基本上是一个或两个虚函数调用。如果每秒执行几十万次,它可能会有所不同,否则,不会重新进行。文件I / O通常很慢,用于访问它的API并不重要。更重要的是读/写模式。很多寻求都很糟糕,顺序读/写都很好。

答案 1 :(得分:4)

它应该稍慢,但就像你说的那样,它可能不是瓶颈。你为什么不描述你的程序,看看是否是这种情况?

答案 2 :(得分:3)

我认为通过从fstream切换到FILE *来解决问题的可能性不大,通常两者都由C库缓冲。 OS也可以缓存读取(linux在这方面非常好)。鉴于您访问的文件大小很可能完全在RAM中。

与PolyThinker一样,您最好的选择是通过分析器运行您的程序,以确定问题所在。

你也在使用seekg / tellg,如果磁盘严重碎片,这会导致明显的延迟,因为首次读取文件磁盘必须将磁头移动到正确的位置。

答案 3 :(得分:2)

所有基准都是邪恶的。只需为您期望的数据配置代码。

我在Ruby,Python,Perl,C ++之间进行了一次I / O性能比较。对于我的数据,语言版本等,C ++的变体速度要慢几倍(当时这是一个很大的惊喜)。

答案 4 :(得分:1)

我同意你应该介绍一下。但是,如果您一次只读取一个字符,那么创建内存映射文件怎么样?这样你可以将文件视为一个字符数组,操作系统应该为你处理所有的低级缓冲。最简单也可能是最快的解决方案是在我的书中获胜。 :)

答案 5 :(得分:0)

Here是一个很好的基准,它表明在极端条件下,fstream实际上非常慢......除非:

  1. 你使用缓冲(我不能强调这一点)
  2. 您自己操纵缓冲区(也就是说,如果您需要链接问题中的OP等性能),这与使用FILE*没有太大区别。
  3. 但是,你不应该过早地进行优化。 fstreams通常会更好,如果您需要在路上优化它们,您可以随时以较低的成本完成此操作。为了提前做好最坏的准备,我建议现在为fstream创建一个最小代理,以便您以后可以对其进行优化,而无需触及任何其他内容。