救命!为什么这段代码执行速度这么慢?

meng699 2006-07-17 05:09:37
用了ExParser控件计算表达式,表达式大约几百个,为什么速度这么慢,1600个数据,200个表达式计算要二分钟!实际我可能对上万个表达式计算,不行啊,怎么办,高手看下代码大概如下,哪有问题怎么能快如飞呢?

全分奉送,务请高手指点!!!

for i:=0 to 1600 do//循环数据
begin
AddVars(i);//设置变量
//Gauge1.Progress:=i;
Label1.Caption:=inttostr(i);
//循环计算所有变量表达式:
for j:=0 to li_gscount-1 do//循环计算每个表达式
begin
ls_1_gs:=memo2.Lines.Strings[j];//取表达式
ls_values:=CalExpr(ls_1_gs);//用上面设的变量计算表达式值
//记录计算结果
if stl_result.Count<j+1 then begin
stl_result.Add(ls_values);
end else begin
stl_result.Strings[j]:=stl_result.Strings[j]+ls_values;
end;
if StopCal then Exit;
Application.ProcessMessages;
end;
Application.ProcessMessages;
ls_values:='';
end;

另注:我把循环中所以的代码去掉,只留下用标签显示进度,都很慢,速度是不去掉任何代码差不多。
数据是从数据库中读的,这里没写出来。
另外,不用数据库,用文本会不会快些呢?
...全文
292 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
meng699 2006-07-19
  • 打赏
  • 举报
回复
YFLK(远方来客) 兄,我把你说的代码去掉了,少量测试,时间还是一样。
所以觉得可能不是它吧,还是计算表达式的慢,我把表达式中变成一般的算术表达式,不用iif,变成如A1-(B2+C3)的形式,速度可以快10倍左右,但速度觉得还是差一些。
谢谢!
YFLK 2006-07-19
  • 打赏
  • 举报
回复
时间开消最大的是这两句
stl_result.Add(ls_values)

stl_result.Strings[j] := stl_result.Strings[j] + ls_values;

想别的办法解决这两句
keyz 2006-07-19
  • 打赏
  • 举报
回复
解释执行是这样的,比较慢。

不知道你的程序要实现什么功能,也许可以通过别的方式解决。
spirit_sheng 2006-07-18
  • 打赏
  • 举报
回复
Application.ProcessMessages;
调用次数太多, 减少此调用次数即可, 例如

if i mod 50 = 0 then
Application.ProcessMessages;
meng699 2006-07-18
  • 打赏
  • 举报
回复
发现主要是这句太慢了,
ls_values:=dm1.ExParser.F([0]);
如果改成 :
ls_values:='0';//不计算试下
就飞快!!!
ExParser计算很慢?还是我的调用方法不对呢,怎么办啊???


meng699 2006-07-18
  • 打赏
  • 举报
回复
谢谢各位了,按大家的意见,我又试了一下:好象和以前不同:
for i:=0 to 1600 do
begin
AddVars(i);

//循环计算所有公式:
for j:=0 to li_gscount-1 do
begin
//ls_1_gs:='iif((KA MOD 10)=(KA1 MOD 10)+(KA2 MOD 10),1,0)'//不用memo用固定的表达式试验。速度看不出提高
ls_1_gs:=memo2.Lines.Strings[j];//此句不改也差不多。暂时没改。
//ls_values:=CalExpr(ls_1_gs);
{ ---这段为计算表达式值的CalExpr函数代码。如果不用它,就飞快,但是不计算不行的。
这样使用ExParser控件有问题吗?是不是反复用它的原因呢?还是这个控件计算速度慢?
dm1.ExParser.Expression.Clear;
dm1.ExParser.Expression.Add(ls_1_gs);
ls_values:=dm1.ExParser.F([0]);
}
if stl_result.Count<j+1 then begin
stl_result.Add(ls_values);
end else begin
stl_result.Strings[j]:=stl_result.Strings[j]+ls_values;
end;
if StopCal then Exit;
end;
if i mod 50 =0 then
begin
Application.ProcessMessages;
Label1.Caption:=inttostr(i);
end;
ls_values:='';
end;
meng699 2006-07-18
  • 打赏
  • 举报
回复
不明白你是怎么测试到的时间。学习。
meng699 2006-07-18
  • 打赏
  • 举报
回复
谢谢keyz,看来是无解了吗,只能这样?晕!!!
谢谢了。
再等等看有没有人有方法。
elilor 2006-07-18
  • 打赏
  • 举报
回复
建议尽量不要在循环中使用控件属性

for i := 0 to 1600 do
begin
AddVars(i);
Label1.Caption := IntToStr(i);
for j := 0 to li_gscount - 1 do
begin
ls_1_gs := memo2.Lines.Strings[j]; //最好在循环前赋值给一个StringList
ls_values := CalExpr(ls_1_gs);
if stl_result.Count < j + 1 then
stl_result.Add(ls_values)
else
stl_result.Strings[j] := stl_result.Strings[j] + ls_values;
if StopCal then
Exit;
end;
Application.ProcessMessages;
end;
luxuewei5214 2006-07-18
  • 打赏
  • 举报
回复
放在单独的线程里吧
keyz 2006-07-18
  • 打赏
  • 举报
回复
看起来是计算的比较慢。你的数据量比较大,我算了一下,如果你有300个表达式,大概0.25ms计算一下,应该还是正常的。
meng699 2006-07-17
  • 打赏
  • 举报
回复
还在等待指点,谢谢,期待中。。。
selfrich 2006-07-17
  • 打赏
  • 举报
回复
UP
meng699 2006-07-17
  • 打赏
  • 举报
回复
我是初学,线程还没弄过,我会试着做下的,我想知道从现在的一个线程的代码上看,有没有什么致命的错误?谢谢二位!!!
YuNal23 2006-07-17
  • 打赏
  • 举报
回复
于那也玩技术
一个线程画界面,一个线程算数据,反映在界面上看看瓶颈在哪里。
andyzhou1101 2006-07-17
  • 打赏
  • 举报
回复
你用线程看看呢

16,749

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 语言基础/算法/系统设计
社区管理员
  • 语言基础/算法/系统设计社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧