CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Delphi >  语言基础/算法/系统设计

如何让程序提速?

楼主fanzai(帆仔)2005-02-23 01:56:09 在 Delphi / 语言基础/算法/系统设计 提问

小弟以前在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

相关问题

  • 如何给CTreeCtrl 提速?
  • 太慢了了,如何提速??
  • 太慢了了,如何提速??
  • 动态追加控件,如何提速?
  • 如何写程序:
  • 如何看程序
  • 程序如何调用另一程序
  • 如何考程序员
  • 如何编图标程序
  • 如何做驱动程序

关键词

  • 数据库
  • 代码
  • 数据
  • delphi
  • adoquerymy
  • 统计
  • 速度
  • 没有

得分解答快速导航

  • 帖主:fanzai
  • aqtata
  • ygflydream
  • liangyong007a
  • 78hgdong
  • Sorder
  • mxj2000
  • TommyTong
  • liangyong007a
  • copy_paste
  • leeshine
  • 快乐老猫
  • smiler007
  • merkey2002
  • liangyong007a
  • 快乐老猫
  • zhmnsw

相关链接

  • Delphi类图书
  • Delphi类源码下载
  • Delphi控件下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo