我被告知我的库比它应该慢,大约30+次解析特定文件(文本文件,大小326 kb)太慢。用户建议我可能正在使用std::ifstream
(大概是FILE
)。
我宁愿不盲目改写,所以我想我先在这里查看,因为我的猜测是其他地方的瓶颈。我正逐字逐句阅读,所以我使用的唯一功能是get()
,peek()
和tellg()/seekg()
。
更新
我描述了,得到了confusing输出 - gprof似乎并没有想到花了这么长时间。我重写了程序,首先将整个文件读入缓冲区,然后加速大约100倍。我认为问题可能是花了很长时间的tellg()/seekg()
,但gprof可能由于某种原因无法看到。在任何情况下,ifstream
不似乎都会缓冲整个文件,即使是这个大小。
答案 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
实际上非常慢......除非:
FILE*
没有太大区别。fstreams
通常会更好,如果您需要在路上优化它们,您可以随时以较低的成本完成此操作。为了提前做好最坏的准备,我建议现在为fstream
创建一个最小代理,以便您以后可以对其进行优化,而无需触及任何其他内容。