如何让程序提速?
小弟以前在VB上写过的一个软件,近日用delphi重写了一遍。
其中有一段代码是对一组数据(3000多条记录)进行指定的统计。原来在VB上,我是使用动态数组来存放数据的,统计速度很快,每间隔1秒统计一次完全没有反应慢的感觉。现在我在delphi中进行同样的统计,统计的方式完全相同,只是数据存在了access数据库中,速度便得超慢,现在每秒一次的统计已经让我的程序几乎不能相应用户事件了。我试了一下,去掉计算部分,只是遍历一遍数据,速度只有少许提升。所以,我估计是数据库操作上太慢了。
想问下delphi下这样的情况有什么好的方法提速没有?
另外,delphi生成的执行文件有没有“发行版”?总感觉按F9生成的调试用的版本肯定要慢很多。
问题点数:100、回复次数:19Top
1 楼aqtata(魔非魔,道非道,善恶在人心)回复于 2005-02-23 08:03:24 得分 5
ctrl + f9就是编译文件呀Top
2 楼ygflydream(飞飞)回复于 2005-02-23 08:22:48 得分 2
up!Top
3 楼liangyong007a((梦里有云,心中有天地)(探花秀))回复于 2005-02-23 08:40:15 得分 5
可能你在循环中反复Close,Open数据库吧。把代码拿来看看:Top
4 楼78hgdong(赤脚)回复于 2005-02-23 09:05:22 得分 2
路过!Top
5 楼Sorder(要才没才,要貌没貌,你还愿意嫁给我吗)回复于 2005-02-23 09:10:26 得分 5
你也同样可以使用数组啊,不要重复不断的去读取数据库,很没有效率的Top
6 楼mxj2000(小马)回复于 2005-02-23 09:17:28 得分 5
在access数据库中和在内存中能比吗?
读硬盘和读内存本来就差一个数量级Top
7 楼fanzai(帆仔)回复于 2005-02-23 09:56:29 得分 0
统计部分完整代码是这样的:
ADOQueryMy:=TADOQuery.Create(nil);
ADOQueryMy.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=data.mdb;Persist Security Info=False';
ADOQueryMy.SQL.Text:='select * from `'+LibUse+'` as selwords,record where selwords.word=record.word and Familiar < 100';
ADOQueryMy.Open();
ADOQueryMy.First();
while not ADOQueryMy.Eof do
begin
if ADOQueryMy.FieldByName('Familiar').AsInteger = 0 then
begin
t1 := 1;
t2 := -1.7E+308;
//t2 = -3.4E+38;
end
else
begin
t1 := Exp(ADOQueryMy.FieldByName('Familiar').AsInteger / 4) / 3600 / 24;
t2 := ADOQueryMy.FieldByName('LastDate').AsDateTime - NowT + t1;
end;
If t2 <= 0 Then
begin
t2 := t2 / t1;
LeftWords := LeftWords + 1;
If t2 < maxneed Then
begin
maxneed := t2;
result := ADOQueryMy.FieldByName('ID').AsInteger;
End;
End;
If (t2 < LeftTime) Or Not LeftExist Then
begin
LeftTime := t2;
LeftExist := True;
End;
ADOQueryMy.Next();
end;
后来改成这样,有点提高,但是和以前相比仍然慢:
ADOQueryMy:=TADOQuery.Create(nil);
ADOQueryMy.ConnectionString:='Provider=Microsoft.Jet.OLEDB.4.0;Data Source=data.mdb;Persist Security Info=False';
ADOQueryMy.SQL.Text:='select * from `'+LibUse+'` as selwords,record where selwords.word=record.word and Familiar < 100';
ADOQueryMy.Open();
ADOQueryMy.First();
while not ADOQueryMy.Eof do
begin
ADOQueryMy.Next();
end;
其中Word在两个数据表里面都是加了索引的。Top
8 楼fanzai(帆仔)回复于 2005-02-23 10:02:43 得分 0
我也想过放在硬盘里速度会降慢的事情,但是我的数据库并不大,700K左右,运行程序时,数据库文件好像都放到缓存里了,很少看到硬盘灯亮。总觉得自己的用法可能不太对头,数据库操作不应该慢到这种地步吧?Top
9 楼TommyTong(童童--寻求兼职……)回复于 2005-02-23 10:34:22 得分 20
在我的Celeon D 1.8G,Windows Server 2003的机器上测试了一下,单表5000条记录,不压缩为15MB左右:
使用默认属性时,单纯遍历时间为957毫秒;
如果设置TADOQuery的CacheSize=100, LockType = ltReadOnly时,单纯遍历时间875毫秒;
如果再进一步设置设置CursorType=ctOpenForwardOnly时,单纯遍历时间为844毫秒;
因此,TADOQuery 本身的执行速度是没有问题的。
我认为你的问题在于SQL语句的写法上,多表关联上可能有错误,导致性能下降。Top
10 楼liangyong007a((梦里有云,心中有天地)(探花秀))回复于 2005-02-23 13:32:49 得分 2
TommyTong(童童--郁闷中……) 说的很精彩呀Top
11 楼copy_paste(木石三)回复于 2005-02-23 13:48:05 得分 7
ADOQueryMy.Open;
ADOQueryMy.DisableControls;
try
ADOQueryMy.First;
while not ADOQueryMy.Eof do
begin
ADOQueryMy.Next;
end;
finally
ADOQueryMy.EnableControls;
end;Top
12 楼leeshine(LeeShine_Soft)回复于 2005-02-23 15:12:44 得分 10
1.在记录很多的大循环里最好不要用ADOQuery.EOF(如:while not ADOQueryMy.Eof do)这样的表达式,应先取记录集中的记录数存于变量中再用for循环,工作效率可提高1/3左右.
2.用存储过程来重写楼主的代码可能会明显提高效率.Top
13 楼快乐老猫(高亚男 无米下炊)回复于 2005-02-23 20:54:48 得分 20
access XP以前的版本是不支持存储过程的,后期的版本设计存储过程也相当吃力。
使用 select * 是个愚蠢的方法,把必要的字段写进去就好了
如果用DAO,连接ACCESS的速度的确比ADO快,因为DAO就是给ACCESS设计的,MS做了最大的优化,不过DELPHI不支持DAO接口。
t2 := -1.7E+308; 有这么大的数么?没必要的话,不要使用过分的数据类型。
尝试用COMMAND对象返回记录看看。
if ADOQueryMy.FieldByName('Familiar').AsInteger = 0 then 这里既然比较的话,最好在SQL里面按照'Familiar'排序,可以提高一定效率。数据库里面最好也给'Familiar'做索引。
要充分利用好SQL语法,SQL是优化数据库速度的一个手段。
Top
14 楼smiler007(笑一笑)回复于 2005-02-23 23:19:15 得分 5
动态创建的AdoQuery,其默认的CacheSize属性是1,此值太小了,加大它到800或900看看,速度会快些的Top
15 楼merkey2002(小样的)回复于 2005-02-24 00:02:45 得分 2
cachesize 值是用来做什么的?
楼上的帮忙解释一下,好吗?Top
16 楼liangyong007a((梦里有云,心中有天地)(探花秀))回复于 2005-02-24 09:18:34 得分 2
顾名思义:好像是高速缓冲存储尺寸Top
17 楼快乐老猫(高亚男 无米下炊)回复于 2005-02-24 11:56:08 得分 5
TO smiler007(笑一笑) :
高,我都没想到这个问题。
实际上应该多跟踪自己的代码,适当的加入时间检查,逐步分析时间浪费的原因。Top
18 楼zhmnsw(糖醋鼻子)回复于 2005-02-24 12:13:36 得分 3
ACCESS数据库本来就很慢的Top
19 楼fanzai(帆仔)回复于 2005-02-24 17:24:50 得分 0
多谢各位了!
这100分我分了好几遍才勉强分好了,分太少,请见谅~~~Top




