关于c ++:std :: ifstream明显慢于FILE吗?

Is std::ifstream significantly slower than FILE?

有人告诉我,我的库比它应该慢30倍以上,解析特定文件(文本文件,大小326 KB)的速度太慢。用户建议可能是我使用的是std::ifstream,而不是FILE

我不想盲目重写,所以我想我应该先检查一下这里,因为我的猜测是瓶颈在其他地方。我正在逐字阅读,所以我使用的功能只有get()peek()tellg()/seekg()

更新:

我分析了一下,然后得到了令人困惑的输出——gprof似乎并没有认为花了这么长时间。我重写了程序,先把整个文件读到一个缓冲区,速度加快了大约100倍。我认为问题可能是tellg()/seekg()花了很长时间,但gprof可能因为某种原因看不到这个问题。在任何情况下,ifstream似乎都不会缓冲整个文件,即使是对于这个大小。


我觉得这没什么区别。特别是如果您正在逐字符地读取数据,那么I/O的开销很可能会完全支配其他任何内容。为什么一次只读取一个字节?你知道它有多低效吗?

在326KB的文件中,最快的解决方案很可能是立即将其读取到内存中。

std::ifstream和c等价物之间的区别,基本上是一个或两个虚拟函数调用。如果每秒执行数千万次,这可能会有所不同,否则就不真实了。文件I/O通常速度很慢,以至于用来访问它的API实际上并不重要。更重要的是读/写模式。很多查找都不好,顺序读/写都很好。


它应该稍微慢一点,但正如您所说,它可能不是瓶颈。你为什么不介绍一下你的程序,看看是不是这样?


我认为不太可能通过从fstream切换到file*来解决您的问题,通常这两者都由C库进行缓冲。操作系统也可以缓存读取(Linux在这方面非常好)。考虑到您正在访问的文件的大小,它很可能完全在RAM中。

就像PolyThinker所说,你最好的选择是通过一个分析器运行你的程序,并确定问题在哪里。

另外,如果您的磁盘严重碎片化,那么使用seekg/tellg可能会导致显著的延迟,因为要第一次读取文件,磁盘必须将磁头移动到正确的位置。


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

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


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


这是一个很好的基准,它表明在极端情况下,fstreams实际上相当慢…除非:

  • 你使用缓冲(我强调不够)
  • 您自己操作缓冲区(也就是说,如果您需要诸如链接问题中的op之类的性能),这与使用FILE*没有什么不同。
  • 不过,你不应该过早优化。fstreams通常更好,如果您需要在路上对它们进行优化,您可以在以后以很低的成本进行优化。为了提前做好最坏情况的准备,我建议现在就为fstream创建一个最小的代理,这样以后您就可以优化它,而无需接触任何其他内容。