如何提高程序的效率,超大文件(200分)

  • 主题发起人 主题发起人 Milpas
  • 开始时间 开始时间
M

Milpas

Unregistered / Unconfirmed
GUEST, unregistred user!
我的程序要读入一个近20M左右的文本,以Readln方式读,
然后以每行做为一个ListItem的Caption
另外还有一个进度条需要更新

发现速度奇慢....

有什么办法可以提度读入速度?
我觉得UltraEdit的速度就很快

另外读入大文件时(如超过100M),系统会不会自动做处理(比如放到虚拟内存中),
还是要我自己做处理?如何处理??
 
什么数据竟然需要20多M?如果数据有规律的话,最好还是用数据库比较好!
 
用这个办法!进度条不要,LISTITEM也不要,等全部读完后,再赋值给LISTITEM
 
你用了ListView吗?如果是可能就它的问题,ListView和TreeView在动态ADD Item时的
速度很慢,建议用StringGrid代替ListView
 
UltraEdit只是读入一部分,不是一次全部读入全部
 
先读一部分,然后再要看其它的内容的时候再读,就会显得快多了.
 
你的进度条最大值是怎么得来的?
 
首先不方便用数据库,用户的数据就是文本的
每个文件的大小并不确定,载入时间会有很大不同,所以还是用进度指示才好
全部读完后才赋值,这个办法可能不好,如果我的文件是100M,那第一次读要开100M内存,赋值时又要开100M内存
不知道用StringGrid代替ListView是否能明显提速?
感觉UltraEdit是一次读入,因为拉滚动条时还是很流畅的
我的进度指示只是一个钟在上面走,没有最大值

欢迎继续讨论,过来拿分...
 
>>首先不方便用数据库,用户的数据就是文本的
是文本为什么就不方便用数据库?
D6提供了TTextDataSet,来方便对文本的操作,这里有个较好的例子http://www.kobira.co.jp/FTP_win/sdfdata.zip。
 
应该可以先读入一部分文本,然后显示。
然后再开一个线程,在后台继续把文本读入,这样,
拖动滚动条的时候就不会很慢了,不过如果拖动太快, 还是会有停顿的
因为这时数据还没有完全读入。
 
用户的数据就是一个文本文件,难道我使用之前还要先把它转成数据库?
如果UltraEdit在打开TXT之前先转成数据库是不是很好笑??
 
Milpas:
最好是看了我提供的例子再评价。
 
试做测试如下:
procedure TForm1.Button1Click(Sender: TObject); //用ListView ShowMessage为“23163”
var
listItem: TListItem;
i,b,e: integer;
begin
b:= GetTickCount;
for i:=0 to 10000 do begin
listItem:= LV.Items.Add;
listItem.Caption:= 'test';
listItem.SubItems.Add('aaaa');
listItem.SubItems.Add('bbbb');
listItem.SubItems.Add('cccc');
end;
e:= GetTickCount;
showmessage(inttostr(e-b));
end;

procedure TForm1.Button2Click(Sender: TObject); //用StringGrid ShowMessage为“450”
var
i,b,e: integer;
begin
b:= GetTickCount;
for i:=0 to 10000 do begin
with StringGrid1 do begin
cells[0,i+1]:= 'Test';
cells[1,i+1]:= 'aaaa';
cells[2,i+1]:= 'bbbb';
cells[3,i+1]:= 'cccc';
RowCount:= RowCount + 1;
end;
end;
e:= GetTickCount;
showmessage(inttostr(e-b));
end;

StringGrid比ListView快得多
 
procedure TForm1.Button1Click(Sender: TObject); //用ListView ShowMessage为“23163”
var
listItem: TListItem;
i,b,e: integer;
begin
b:= GetTickCount;
LV.items.BeginUpdate;
for i:=0 to 10000 do begin
listItem:= LV.Items.Add;
listItem.Caption:= 'test';
listItem.SubItems.Add('aaaa');
listItem.SubItems.Add('bbbb');
listItem.SubItems.Add('cccc');
end;
LV.items.EndUpdate
e:= GetTickCount;
showmessage(inttostr(e-b));
end;

借楼上代码一用,这样快很多.
BeginUpdate EndUpdate
 
savenight:
我下了那个ZIP,因为有控件要装,并且我看了它的README.TXT,说只对两种特定的文本格式有效,
因为我的文本不需要做格式处理,也不需要其它的数据库排序,分类,统计之类的操作,
所以没有试....我不知道效果如何
 
如果我不一次全部读入,有什么知道文本有多行吗?

用土一点的办法:
while not eof(f) do
begin
readln(f)
Inc(ln);
end;
实际上也是要读一遍,应该也是很耗时吧?
 
除非每行是固定长度的,否则只能全部读一遍才能知道
 
to wangpian:

加入BeginUpdate和EndUpdate之后,ShowMessage显示为21xxx or 22xxx。
ListView慢的原因不在于Redraw的过程,我想是因为它为每个ListItem都创建了一个TList
对象,用来存贮SubItem中的信息,包括可能的 String 和 Image 对象。ListView是可以
显示图片的。
 
我是这样做的:
用一个STRING来做缓存,读一两千行,然后再复制给RICHEDIT
(或者你的情况用TSTRINGLIST,复制给LISTITEM)
之所以慢,是因为每次读一行直接复制给RICHEDIT或LISTITEM,
都会刷新一下显示,这样会大大降低速度
 

Similar threads

后退
顶部