TStringList.Free为什么如此慢?(50分)

A

Adnil

Unregistered / Unconfirmed
GUEST, unregistred user!
示例代码:

procedure TForm1.Button1Click(Sender: TObject);
var
a: tstringlist;
i: integer;
t: cardinal;
begin
a := tstringlist.create;
for i := 1 to 1000000 do
a.Add('hahahah!hahahah!hahahah!hahahah!');
t := gettickcount;
a.Free;
showmessage(inttostr(gettickcount-t));
end;

其中a.Free在我的PIII500机器上快要耗费1秒钟的时间,因为我的程序经常需要对
大量的字符串进行操作,例如例子中的1000000,我该如何优化算法,让StringList
释放的速度快一些呢?
 
好象没什么好办法呀,除非提高硬件的配置。
释放的时间同字符的多少基本成正比关系。
t := gettickcount;
a := tstringlist.create;
for i := 1 to 1000000 do
a.Add('hahahah');
label1.Caption :=inttostr(gettickcount-t);
t := gettickcount;
a.Clear
label2.Caption :=inttostr(gettickcount-t);
t := gettickcount;
a.free
label3.Caption :=inttostr(gettickcount-t);
从这个例子可以看出来,主要是清除内存中的字符数据占用了时间,而真正的释放占用时间并不长。
 
你的代码肯定没有问题,在你的例子中,操作 1000000个字符串,
至少要占用 30M内存。
如果下次还要用到,不一定马上释放,可以考虑用全局变量。
不要太频繁地释放。
也可以考虑放在线程中处理。
也可以考虑用数据库。

我试了一下,clear 和 free 的效果差不多。
 
你的系统设计有严重的问题。无论采用什么方法,要释放数十M的内存都要秒级的时间。
说说你的应用,大家看看能否从根本上进行改良。
 
30M内存应该用虚拟内存来实现,用堆来保存这么大的数据肯定很慢
 
to creation-zy:
我要对一个结果集某一列进行Buffer,将该列的所有数据缓存至StringList,
然后释放结果集。这样做的好处是立即可释放数据库链接,释放结果集内存(
结果集内存耗费更加厉害)

谢谢指教。
 
呵呵,,你用一个内存表来做,现在有现成的控件
 
我不想用控件,自己实现好一些。
就算用内存表控件,我想也不能解决问题。
 

好一点,可能有一半


var
a: tstringlist;
i: integer;
t: cardinal;
begin
a := tstringlist.create;
for i := 1 to 1000000 do
a.Add('hahahah!hahahah!hahahah!hahahah!');
t := gettickcount;
for i := 999999 to 0 do
a.Delete(i);
a.Free;
showmessage(inttostr(gettickcount-t));
 
如果不是要求随机检索和排序,也可以自己动态分配内存,不用TList或者干脆使用静态分配
 
to mtj:你这样只会更加慢

to tseug:我考虑过使用动态数组的方法array of string来缓存,但是有时需要
对缓存进行修改,例如增加和删除,这样的话,重新分配所占的资源后更加厉害,
每次都需要重新分配。
 
To Adnil:
我建议你用虚拟内存来管理这么大的内存块。
 
to 张无忌:可以给些范例吗?
 
张无忌,能说一下你是怎么使用虚拟内存?[:)]
 
VirtualAlloc()
VirtualFree()
具体的使用例子都是VC的,
你如果想了解如何使用,可以看MSDN
 
用VirtualAlloc()和VirtualFree()对于我的问题来说有什么优点吗?
 
虚拟内存适合管理大量的数据,系统会把暂时不用的数据转移到硬盘上,自动控制内存的

只有你把他提交存储器以后才算把他写入内存
 
to 张无忌:
对我来说没有意义,就如我的第一贴所提的,我在乎的是速度。 数据是临时写在硬盘
还是写在内存,关系并不大,而且,我并不希望将缓存转移到硬盘上,这样速度更加慢。
 
你不会一次处理完所有的30M数据把,在你处理其中一部分数据的时候,系统同时把
其他的数据从硬盘上转移到内存里,把不用的数据转移到硬盘上,这样减少了内存的
占用,提高了效率。
 

Similar threads

D
回复
0
查看
2K
DelphiTeacher的专栏
D
S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
892
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
顶部 底部