首页 > 代码库 > 读取大文件时的优化经验

读取大文件时的优化经验

    最近在编写一个关于图形学的东西时,由于需要读取模型,写了一个obj文件和mtl文件解析器。实际调试时,由于该文件较长,比如obj文件达到了20万行的量级,在解析时凸显出了各种性能问题,解决这些性能问题的同时,也总结出了一些经验,记录如下:


1 必须使用缓冲区。虽然操作系统实现读取文件应该是有缓冲区概念的,但是结果显示如果不使用缓冲区,而用fgetc挨个字符进行读取,速度会比使用缓冲区慢上1个数量级。因此,引出第一条经验:一切大文件读取必须使用缓冲区,减少fread或fgetc的次数。


2 关于map。vector和map的性能是可以依赖的。虽然debug的时候,插入map的时间总和达到了好几秒的量级,但在release模式下,优化充分的map插入时间变成了几十毫秒,因此可以放心的使用stl的map。


3 关于vector。vector的reserve函数使用以后并不会有特别大的效果,由于vector的内存池优化比较好,实在没有必要在一开始就reserve,因为临时扩展,所耗费的时间甚至小于两次测量的误差。 


4 ftell函数也是耗时的!我的某个读取函数一开始调用了ftell,这个函数一直稳定的耗费2.5秒左右时间。我起初并不怀疑ftell,毕竟这个函数怎么看怎么像无io阻塞,o(1)的东西。没想到去掉ftell的调用后这个函数直接缩减到了耗费25毫秒,少了2个量级。因此还是这句话,所有io函数都少用为妙,自己维护缓冲区,指针才是王道。

 
    至于ftell为什么这么慢,我猜想是内部调用了api访问了文件内核对象的缘故 


最后经过优化的解析器,读取20万行的obj文件使用740毫秒,不算特别快的速度,不过暂时优化就到此为止了,以后有时间再进一步搞。

读取大文件时的优化经验