ion*_*ion 5 delphi optimization
我的项目涉及历史和实时数据分析.在其最后阶段包含几个复杂的算法(超过800).总体而言,分析阶段大致如下:
这些第三阶段公式是复杂条件的大块.但是,这些复杂的条件使用了有限数量的简单语句.结果,这些简单的陈述在复杂的条件中重复了很多次.让我举一个非常简单的例子.
if ((var1[0]<var2[0]*0.5)and(var3[0]=1))or(var15[1]<>var15[0]))
....lots of similar statements....
then take action.
Run Code Online (Sandbox Code Playgroud)
现在,声明如
"(var3[0]=1)" or "(var15[1]<>var15[0])"
Run Code Online (Sandbox Code Playgroud)
在其他if块中反复使用.我的想法是解析所有这些独特的简单语句,并自动创建一些计算结果的代码(true/false),并在第三阶段开始之前将它们存储在布尔数组中.像这样:
arr[12]:=var1[0]<var2[0]*0.5;
arr[13]:=var3[0]=1;
...
arr[128]:=var15[1]<>var15[0];
Run Code Online (Sandbox Code Playgroud)
然后(再次通过在编译之前解析我的代码)将simpler语句替换为其相应的数组元素.所以,而不是
if ((var1[0]<var2[0]*0.5)and(var3[0]=1))or(var15[1]<>var15[0]))
Run Code Online (Sandbox Code Playgroud)
看起来像
if ((arr[12])and(arr[13]))or(arr[128])
Run Code Online (Sandbox Code Playgroud)
我的代码中的这些更改会加快执行(计算)时间吗?或者编译器已经做了类似的事情,我只是在浪费时间?请记住,在每个计算周期中,这些简单的语句会重复数十次或数百次.并且在实时数据启动之前至少要计算300,000个周期.因此,每一点都有帮助.本质上我问的是变量之间的比较是否慢于检索布尔数组元素的值;
UPDATE
由于有些人要求一些真实的代码,这里是真实代码的一部分.98%的代码是变量(带有[0]的所有内容都是允许访问先前变量值的变量).2%是功能.变量在前一阶段计算.几乎所有变量都是整数.总共有800多个类似的块.最少300,000个计算周期.平均时间约为45秒.由于我不需要在这里解释的原因,我应该使它快2倍.如果编写算法的人是程序员,代码可能会有不同的形式.但他们不是.他们可以处理一些基本的东西,如条件块.这是无法改变的.
我注意到有些人来这里打算表达讽刺意味.请远离.我不需要你的帮助.那些愿意提供建设性意见的人非常欢迎这样做.事实上,我提前感谢他们只是努力阅读这么长的帖子.我很抱歉错误的代码格式化,这是一个失败的努力将其作为代码发布在这里.
if ( ZEChT01Pc[0] < ZEChT02Pc[0])
and( ZEChP01Pc[0] < ZEChP02Pc[0])
and( ZEChT01Bn[0] > ZEChP01Bn[0])
and( BncUp_TL_P_1_2[0] > ZEChT01Bn[0])
and( higSncZEChT01[0] < HZigCh30[0])
and( ((ZEChT01Pc[0] < LZigCh30[0]) )
or
( (ZEChT01Pc[0] < LZigCh3002[0] ) and( LZigCh30[0] < LZigCh3002[0] ) and( ZEChT01Pc[0] <= Bnc_Up_HZigCh_Pr[0]) )
or
( (ZEChT01Pc[0] < LZigCh3002[0] ) and( LZigCh30[0] < LZigCh3002[0] ) and( ZEChT01Pc[0] > Bnc_Up_HZigCh_Pr[0] ) and( ZEChP02Pc[0] < TFZ11EndPc[0])) )
and( ((TL_Pks_1_2.tl_getvalue(0) < LZigCh30[0] + ((HZigCh30[0] - LZigCh30[0] )*0.80)) )
or
( (ZEChT01Pc[0] < ULX2dly[0] ) and( C[0] > DLX2dly[0])) )
and (( (ZECoP01Bn[0] > ZEChP01Bn[0]) and (ZECoP01Bn[0] < ZEChT01Bn[0])
and (( (ZECoP01Pc[0] <= ZECoP02Pc[0]) and (C[0] > TL_ECo_Trs_1_2.tl_getvalue(0) )) or ( (ZECoP01Pc[0] > ZECoP02Pc[0]) )) )
or
( (ZECoP01Bn[0] = ZEChP01Bn[0]) and (ZECoP02Bn[0] < ZEChT02Bn[0]) ))
and (( (C[0] > ULX30[0]) and (C[1] <= ULX30[0]) and (ULX30[0] > TL_Pks_1_2.tl_getValue(0))
and (( (BrUpULX30[1] < ZEchT01Bn[0]) ) or ( (chgZigLCh[0] > BrUpULX30[1]) )) )
or
( (C[0] > TL_Pks_1_2.tl_getvalue(0)) and (C[1] <= TL_Pks_1_2.tl_getvalue(0)) and ( TL_Pks_1_2.tl_getValue(0) > ULX30[0]) and (BncUp_TL_P_1_2[1] < ZEchT01Bn[0]) ))
and( ((uniBrUpULX3002_bn[0] > ZEChT01Bn[0] ) and( uniBrUpULX30[0] > TL_Pks_1_2.tl_getvalue(0) ) and( uniBrUpULX3002[0] < TL_Pks_1_2.tl_getvalue(0)) )= false)
and( ((uniBrUpULX3002_bn[0] > ZEChT01Bn[0] ) and( uniBrUpULX30[0] > TL_Pks_1_2.tl_getvalue(0) ) and( uniBrUpULX3002[0] > TL_Pks_1_2.tl_getvalue(0)) )= false)
and( NoLong[0] = 0)
and( ((TL_Pks_1_2.tl_getvalue(0) < LZigCh30[0] ) and( chgZigLCh[0] < ZEChT01Bn[0] ) and( ULX30[0] > LZigCh30[0]) )= false)
and( ((((C[0] < DLXdly[0] ) and( HZigCh30[0] < DLXdly[0] - Tk(0.0050)) = false)))
or
( (ZEChT01Bn[0] = TFZ10EndBnum[0] ) and( ZEChT01Pc[0] < TFZ20EndPc[0] ) and( higSncZEChT01[0] > TFZ40EndPc[0])) )
and( ((ZEChP01Pc[0] > DLXdly[0] ) and( ZEChT01Pc[0] < DLXdly[0] ) and( HZigCh30[0] < DLXdly[0] )) = false)
and( ((higSncZEChT01[0] > HZigCh30[0] -Tk(0.0010) ) and( Bnc_Dn_HZigCh[0] > higbarSncZEChT01[0]) )= false)
and( ((TFZ10EndBnum[0] > TFZ11EndBnum[0] ) and( TFZ10Type[0]= 5 ) and( TFZ10Extension[0] = 0 ) and( ULX30[0] < LZigCh30[0]) )= false)
and( ((Bnc_Dn_LZigCh[0] > ZEChT01Bn[0] ) and( C[0] < LZigCh30[0]) )= false)
and( ((ZEChP01Pc[0] > DLXdly[0] ) and( ZEChT01Pc[0] < DLXdly[0] ) and( C[0] < DLXdly[0] ) and( First[0] = -1) )= false)
and( ((LZigCh3002[0] > DLXdly[0] ) and( LZigCh30[0] < DLXdly[0] ) and( C[0] < DLXdly[0]) and( HZigCh3002[0] > DLXdly[0] ) and( HZigCh30[0] < DLXdly[0] )) = false)
and( ((LZigCh3003[0] > DLXdly[0] ) and( LZigCh3002[0] < DLXdly[0] ) and( C[0] < DLXdly[0])
and( HZigCh3002[0] > DLXdly[0] ) and( HZigCh30[0] < DLXdly[0] ) and( LZigCh30[0] < DLXdly[0] ) and( currentbar - chgZigLCh[0] <= 3 )) = false)
and( ((((TFZ10EndBnum[0] > TFZ11EndBnum[0] ) and( C[0] > higSncShFrm[0] - ((higSncShFrm[0] - TFZ10EndPc[0])*0.5) ) and( higBarSncShFrm[0] <= ZEChP02Bn[0]) = false)))
or
( (ZEChT01Pc[0] < DLXdly[0] ) and( C[0] > DLXdly[0])) )
and( ((C[0] <= LZigCh30[0] ) and( H[0] > LZigCh30[0]) = false))
and( ((ZEChT01Pc[0] < ULXdly[0] ) and( ZEChT02Pc[0] < ULXdly[0] ) and( ZEChP01Pc[0] > ULXdly[0] )
and( ZEChP02Pc[0] > ULXdly[0] ) and( ZEChT01Pc[0] < ZEChT02Pc[0]) and (BncUpDLXdly[0] < ZEchT01Bn[0]) )= false)
and( ((((TFZ11EndBnum[0] > TFZ10EndBnum[0] ) and( ZEChT01Pc[0] > TFZ11EndPc[0] - ((TFZ11EndPc[0] - TFZ10EndPc[0])*0.382)) = false)))
or
( (C[0] > ULXdly[0])) )
and( ((((TFZ10EndBnum[0] > TFZ11EndBnum[0] ) and( TFZ20EndBnum[0] < TFZ11EndBnum[0] ) and( ZEChT01Pc[0] > TFZ11EndPc[0] - ((TFZ11EndPc[0] - TFZ20EndPc[0])*0.382)) )= false))
or
( (C[0] > ULXdly[0])) )
and( ((((TFZ20EndBnum[0] > TFZ11EndBnum[0] ) and( TFZ30EndBnum[0] < TFZ11EndBnum[0] ) and( ZEChT01Pc[0] > TFZ11EndPc[0] - ((TFZ11EndPc[0] - TFZ30EndPc[0])*0.382)) )= false))
or
( (C[0] > ULXdly[0])))
and( ((((TFZ30EndBnum[0] > TFZ11EndBnum[0] ) and( TFZ40EndBnum[0] < TFZ11EndBnum[0] ) and( ZEChT01Pc[0] > TFZ11EndPc[0] - ((TFZ11EndPc[0] - TFZ40EndPc[0])*0.382)) )= false))
or
( (C[0] > ULXdly[0])))
and( ((ZEChP01Pc[0] > ZEChP03Pc[0] ) and( ZEChP01Pc[0] > ZEChP04Pc[0] ) and( C[0] < DLXdly[0]) = false) )
and (( (( (LZigCh30[0] < DLXdly[0] ) and( LZigCh3002[0] > DLXdly[0] ) and( ZEChP01Pc[0] < DLXdly[0] ) and( C[0] < DLXdly[0]) ) = false))
or
( (ZEchT01Pc[0] = TFZ10EndPc[0]) or (ZEchT02Pc[0] = TFZ20EndPc[0]) or (ZEchT03Pc[0] = TFZ30EndPc[0]) ))
and( NoLong2[0] = 0 )
and( ((ZEChP02Pc[0] > ULX2dly[0] ) and( ZEChP01Pc[0] < ULXdly[0] ) and( C[0] < ULX2dly[0] ) and( BrDnDLXdly[0] < BrUpULXdly[0])
and( Min(ZEChT01Pc[0],ZEChT02Pc[0]) > ULXdly[0] - ((ULXdly[0] - DLXdly[0]) * 0.618)) )= false)
and( ((BrDnDLXdly[0] < BrUpULXdly[0] ) and( Min(ZEChT01Pc[0],ZEChT02Pc[0]) > ULXdly[0] - ((ULXdly[0] - DLXdly[0]) * 0.4))
and( TFZ10EndBnum[0] > TFZ11EndBnum[0] ) and( C[0] < ULX2dly[0] ) and( ULXdly[0] > ULX2dly[0] ) )= false)
and( ((BrDnDLXdly[0] < BrUpULXdly[0] ) and( TFZ10EndPc[0] > ULXdly[0] - ((ULXdly[0] - DLXdly[0]) * 0.4))
and( TFZ10EndBnum[0] < TFZ11EndBnum[0] ) and( C[0] < ULX2dly[0] ) and( ULXdly[0] > ULX2dly[0] ) )= false)
and( ((ZEChP02Pc[0] > ULX2dly[0] ) and( ZEChP01Pc[0] < ULXdly[0] ) and( C[0] < ULX2dly[0] ) and( BrDnDLXdly[0] < BrUpULXdly[0])
and( C[0] > LZigCh30[0] + ((HZigCh30[0] - LZigCh30[0]) * 0.768) ) and( C[0] < ULX2dly[0]) )= false)
and( ((LZigCh30[0] < DLXdly[0] ) and( DLXdly[0] < HZigCh30[0] ) and( C[0] > LZigCh30[0] + ((DLXdly[0] - LZigCh30[0])*0.618))
and( DLXdly[0] - C[0] < Tk(0.0040) ) and( C[0] < DLXdly[0] ) )= false)
and( ((((ZEChT01Bn[0] <> TFZ10EndBnum[0] ) and( ZEChT01Pc[0] >= LZigCh30[0])) = false))
or
( (ZEChT01Pc[0] < LZigCh30[0] ) and( C[0] > LZigCh30[0] ) and( LZigCh30[0] > ULXdly[0]))
or
( (LZigCh30[0] < LZigCh3002[0] ) and( chgZigLCh[0] > ZEChT01Bn[0] ) and( ZEChP01Pc[0] < LZigCh3002[0] ) and( C[0] > ZEChT02Pc[0] ) )
or
( (ZEChT01Pc[0] <= DLXdly[0] ) and( C[0] > DLXdly[0])))
and( ((C[0] < TFZ20EndPc[0] ) and( C[0] < LZigCh3002[0] ) and( TFZ20Type[0] > 3 ) and( ((TFZ20EndBnum[0] = ZEChT02Bn[0]) )or( (TFZ20EndBnum[0] = ZEChT03Bn[0]))) )= false)
and( ((((ZEChT01Bn[0] <> TFZ10EndBnum[0] ) and( ZEChT01Pc[0] < LZigCh30[0] ) and( LZigCh30[0] > ULXdly[0]) )= false))
or
( (C[0] < LZigCh30[0] + ((HZigCh30[0] - LZigCh30[0] )*0.618) ) and( HZigCh30[0] - C[0] >= Tk(0.0040)) ))
and( ((LZigCh30[0] < DLXdly[0] ) and( LZigCh3002[0] > DLXdly[0] ) and( ZEChP02Pc[0] < DLXdly[0] + Tk(0.0050) )
and( ZEChP02Pc[0] < LZigCh3002[0] ) and( C[0] < LZigCh3002[0] ) = false))
and ( (( (HZigCh30[0] < DLXdly[0]) and (HZigCh3002[0] > DLXdly[0]) and (ZEchT01Bn[0] = TFZ10EndBnum[0])
and (TFZ10Type[0] = 5 ) and (TFZ10Extension[0] = 0) and (DLXdly[0] < DLX2dly[0]) ) = false) )
and (( (( (chgULXdly[0] > ZEchP01Bn[0]) and (ULXdly[0] > ULX2dly[0]) and (C[0] < ULXdly[0]) and (ZEchT01Pc[0] > ULX2dly[0]) )=false))
or
( (TFZ10EndBnum[0] = ZEchT01Bn[0]) and (TFZ10Type[0] > 3) ))
and (( (( (chgULXdly[0] > ZEchP01Bn[0]) and (ULXdly[0] > ULX2dly[0]) and (C[0] < ULXdly[0]) and (C[0] < ULX2dly[0]))= false))
or
( ( ZechT01Pc[0] < ULXdly[0] - ((ULXdly[0] - DLXdly[0])*0.75)) and (C[0] > LZigCh30[0]) and (DLX30[0] > LZigCh30[0]) ))
and (( (( (chgULXdly[0] > ZEchP01Bn[0]) and (ULXdly[0] < ULX2dly[0]) and (C[0] < ULXdly[0]) ) = false))
or
( ( ZechT01Pc[0] < ULXdly[0] - ((ULXdly[0] - DLXdly[0])*0.75)) and (C[0] > LZigCh30[0]) and (DLX30[0] > LZigCh30[0]) ))
and (( (TFZ11EndBnum[0] = ZEchP02Bn[0]) and (TFZ11Type[0] > 3) and (min(ZEchT01Pc[0],ZechT02Pc[0]) = TFZ10EndPc[0]) and (C[0] < ULXdly[0])
and (TFZ10Type[0] = 3) and (TFZ10Extension[0] = 2) and (TFZ10EndPc[0] > ULXdly[0] - ((ULXdly[0] - DLXdly[0])*0.5)) ) = false)
and (( (TFZ11EndBnum[0] = ZEchP02Bn[0]) and (TFZ11Type[0] > 3) and (min(ZEchT01Pc[0],ZechT02Pc[0]) = TFZ10EndPc[0]) and (C[0] < ULXdly[0])
and (( (TFZ10Type[0] = 3) and (TFZ10Extension[0] = 2) )= false) and (TFZ10EndPc[0] > ULXdly[0] - ((ULXdly[0] - DLXdly[0])*0.8)) ) = false)
and (( (( (TFZ11EndBnum[0] = ZEchP02Bn[0]) and (TFZ11Type[0] > 3) and (min(ZEchT01Pc[0],ZechT02Pc[0]) <> TFZ10EndPc[0])) = false))
or
( (min(ZEchT01Pc[0],ZechT02Pc[0]) < ULXdly[0] - ((ULXdly[0] - DLXdly[0])*0.8)) )
or
( (Bnc_Up_LZigCh[0] > ZEchT01Bn[0]) and (ZEchT01Pc[0] > ZechP03Pc[0]) ))
and (( (ZechT01Pc[0] < ZechT02Pc[0]) and (ZechP01Pc[0] < ZechP02Pc[0]) and (ZEchT01Pc[0] > ULXdly[0]) and (C[0] < ZEchT02Pc[0]) and (C[0] > ULXdly[0]) ) = false)
and (( (ZechT01Pc[0] < ZechT02Pc[0]) and (ZechP01Pc[0] < ZechP02Pc[0]) and (ZEchT01Pc[0] > ULXdly[0]) and (ZEchP02Bn[0] = TFZ11EndBnum[0])
and (ZEchT02Bn[0]= TFZ20EndBnum[0]) and (ZEchT01Bn[0]= TFZ10EndBnum[0]) and (TFZ10Type[0] = 3) and (C[0] > ULXdly[0]) )= false)
and (( (ZechT01Pc[0] < ZechT02Pc[0]) and (ZechP01Pc[0] < ZechP02Pc[0]) and (ZEchT01Pc[0] > ULXdly[0]) and (ZEchP03Bn[0] = TFZ11EndBnum[0])
and (ZEchT02Bn[0]= TFZ20EndBnum[0]) and (ZEchT01Bn[0]= TFZ10EndBnum[0]) and (TFZ10Type[0] = 3) and (C[0] > ULXdly[0]) )= false)
and (((( (TFZ10Type[0] = 7) and (TFZ20type[0] = 5) and (TFZ10Extension[0] = 0) and (TFZ20Extension[0] = 0) and (TFZ10EndPc[0] > ULXdly[0] - ((ULXdly[0] - DLXdly[0])*0.5))) = false))
or
( (C[0] > ULXdly[0]) ) or ( (ZechT01Pc[0] < ULX2dly[0] ) and (C[0] > ULX2dly[0]) and (ULX2dly[0] < ULXdly[0]) ))
and (( (max(HZigCh30[0],HZigCh3002[0]) - LZigCh30[0] < Tk(0.0100)) and (C[0] > LZigCh30[0] + ((max(HZigCh30[0],HZigCh3002[0]) - LZigCh30[0])*0.618)) ) = false)
and (( (ZEchP02Pc[0] > ULXdly[0] - ((ULXdly[0] - DLXdly[0])*0.236)) and (ZEchT01Bn[0] <> TFZ10EndBnum[0]) and (BncUpDLXdly[0] < ZEchT01Bn[0])) = false)
and (( (Bnc_Dn_LZigCh[0] > ZEChT01Bn[0] ) and (C[0] < LZigCh30[0]) ) = false)
and (( (TFZ41EndBnum[0] > TFZ10EndBnum[0]) and (C[0] < ULXdly[0]) and (BncUpDLXdly[0] < ZEchT01Bn[0]) ) = false)
and ( GenL01[0] = false)
and ( GenL02[0] = false)
and ( GenL03[0] = false)
and ( GenL04[0] = True)
then
Run Code Online (Sandbox Code Playgroud)
谢谢你的阅读.
从软件开发的角度来看,您的方法存在严重缺陷.代码if ((arr[12])and(arr[13]))or(arr[128])基本上是不可读和不可维护的.
您应该为常用的布尔值创建属性,并为它们指定有意义的名称.如果您发现很难命名一个属性,那么不要害怕写
if height>CriticalHeight then
Run Code Online (Sandbox Code Playgroud)
根据我的经验,缓存这些测试结果的性能优势将无法衡量.您当前的方法肯定会导致缺陷和错误的代码.
正如您所指出的,我肯定会将结果存储在数组中。编译器不知道您正在计算的值,并且不会将结果存储在某些临时堆栈中,以防出现重复公式。这就是变量的用途。
所以是的,这会加快你的计算时间。
更新
这里是 Delphi 2009 生成的简单示例和反汇编。正如您所见,在反汇编中将结果存储到变量需要一些 CPU 周期,但比较数组中的布尔值只需要 4 个指令。因此,如果您保存一次结果,那么您的比较将仅采用这 4 条指令,而不是每次 14 条指令。
您可以通过在调试模式下输入断点并从“查看”/“调试窗口”/“CPU Windows”/“反汇编”显示“反汇编”窗口来查看反汇编。
请注意,根据您的 Delphi 版本,这可能会略有不同。
procedure TForm1.Button1Click(Sender: TObject);
var
Result: Boolean;
X: array [0..1] of Double;
Y: array [0..1] of Double;
begin
X[0] := 0.25;
X[1] := 0.75;
Y[0] := 0.25;
Y[1] := 0.75;
if (X[0] < X[1] * 0.5) and (Y[0] < Y[1] * 0.5) then
Result := True;
if Result then
ShowMessage('Result = True'); // to prevent optimization
end;
procedure TForm1.Button2Click(Sender: TObject);
var
Result: Boolean;
X: array [0..1] of Double;
Y: array [0..1] of Double;
Z: array [0..1] of Boolean;
begin
X[0] := 0.25;
X[1] := 0.75;
Y[0] := 0.25;
Y[1] := 0.75;
Z[0] := (X[0] < X[1] * 0.5);
Z[1] := (Y[0] < Y[1] * 0.5);
if Z[0] and Z[1] then
Result := True;
if Result then
ShowMessage('Result = True'); // to prevent optimization
end;
Run Code Online (Sandbox Code Playgroud)
拆解时点击
Button1可以看到直接对比
if (X[0] < X[1] * 0.5) and (Y[0] < Y[1] * 0.5) then
-----------------------------------------------------
fld qword ptr [esp+$08]
fmul dword ptr [$0046cdbc]
fcomp qword ptr [esp]
wait
fstsw ax
sahf
jbe $0046cda7
fld qword ptr [esp+$18]
fmul dword ptr [$0046cdbc]
fcomp qword ptr [esp+$10]
wait
fstsw ax
sahf
jbe $0046cda7
Result := True;
-----------------------------------------------------
mov dl,$01
Run Code Online (Sandbox Code Playgroud)
在 Button2Click 中,结果的存储需要一些时间,但比较本身只需要 4 条指令
Z[0] := (X[0] < X[1] * 0.5);
-----------------------------------------------------
fld qword ptr [esp+$10]
fmul dword ptr [$0046ce78]
fcomp qword ptr [esp+$08]
wait
fstsw ax
sahf
setnbe al
mov [esp],al
Z[1] := (Y[0] < Y[1] * 0.5);
-----------------------------------------------------
fld qword ptr [esp+$20]
fmul dword ptr [$0046ce78]
fcomp qword ptr [esp+$18]
wait
fstsw ax
sahf
setnbe al
mov [esp+$01],al
if Z[0] and Z[1] then
-----------------------------------------------------
cmp byte ptr [esp],$00
jz $0046ce63
cmp byte ptr [esp+$01],$00
jz $0046ce63
Result := True;
-----------------------------------------------------
mov dl,$01
Run Code Online (Sandbox Code Playgroud)