1 程序背景:
  扫描用户指定的路径下的以某一个后缀结尾的文件,暂定为.srh,然后通过文件映射的方式从文件头读出一些信息,然后把这些信息形成一行记录存入一个文本文件中。扫描后的文件信息存入TStringList中,然后逐一打开然后取信息,把信息存入另外一个TStringList中,然后存入文本文件中。
  2.问题:
  当用户的文件数在1W-2W这个区间,处理的速度很快,经验值是1W,20s,2W,1分钟,后来我找了一个18W个文件数来试验,结果用了4个多小时,18W/2W * 1 = 9分钟,但是结果却是4个小时,这个差的太远了。
  3.分析可能性:
    1)查找文件很慢。的确,文件数多了,查询的速度比较慢,但是差别不大,结果比较满意。
    2)TStringList在数据量大的时候需要改写capability造成的?一次性将其capability改为20W,效率上没什么提高
    3)多线程,亦不凑效
    4)有人说TStringList在Count<=5000的情况下很有效率,于是在记录满了5000,就先存入文件中,然后清除TStringList,结果还是不让人满意。。
    5)无奈至极,到CSDN发帖求助。
  4.补充说明:处理的文件本身不大,基本维持在5M左右,我映射的时候只映射我需要的那个结构的大小,获取信息之后就马上关掉。可以说这个程序的IO操作频繁,但是计算量不大,所以程序运行的时候,不怎么吃CPU,这也是效率提不起来的问题

解决方案 »

  1.   

    一般就是用LOG显示,将可能使效率的地方显示出来
    如:for i := 0 to FileList.Count - 1 do
    [
      starttime = gettickcount;
      DoMyJob(...);
      Time = GetTickCount - StartTime;
      // 大于10S的显示一下
      if Time > 10000 then
        Memo1.lines.add(FileList[I] + '花费了:' + InttoStr(Time);
    ]找到费时间的了,就找到对应DoMyJob那函数里,再显示更详细的日志,一点点分析,没啥技艺
      

  2.   

    以前我用TStringList做的日志文件解析器,上百万数据,还要解析匹配,都是没到100ms.
    基本上条件一边输入,符合的条件的结果们就列出来了.毫无延迟.
    如果楼主确定不是查找文件的影响就是你的用法或者设计模型有问题了
      

  3.   

    估计瓶颈还是磁盘IO上,不断打开文件,读取头,再关闭文件这个过程耗费的时间最久操作系统的cache一旦用完,每次都是实实在在的磁盘访问,速度会越来越慢和tsringlist的关系不大想优化,还要先看慢的时候磁盘IO的负载是不是很高?方法无外乎就是多线程加自定义缓冲区