Jan*_*gen 1 delphi optimization delphi-xe2
在我维护的一些代码中,我看到TClientDataSet.OnCalcFields事件处理程序中使用了两种不同的方法:
with DataSet do
begin
// 1. Call FieldByName twice
if AMinDate > FieldByName(SPlanAllocatieFromDate).AsDateTime then
AMinDate := FieldByName(sPlanAllocatieFromDate).AsDateTime;
// 2. Put the retrieved FieldByName value in a temp var
lEmpID := FieldByName(SPlanAllocatieEmpID).AsInteger;
if lEmpID <> 0 then lTSAllocatedEmpIDs.Add(IntToStr(lEmpID));
end;
Run Code Online (Sandbox Code Playgroud)
编译器(Delphi XE2,Win32 app)是否会优化方法2以使用temp var?这两个FieldByNames非常接近,你甚至可以说是嵌套的.
如果没有,我应该重写1.因为OnCalcFields经常执行.
BTW.我知道Fields []和FieldByName(),或者在运行EOF循环时使用temp TField var,这些不是问题.
没有任何版本的Delphi编译器可以做这样的事情.
这种优化需要编译器能够证明对FieldByName的两次调用总是给出相同的结果,并且目前没有规定将方法标记为确定性的.
注意,理论上很可能(如果不可能实际上)两个调用不给出相同的结果,在这种情况下,例如,如果不同的线程在第一次和第二次调用之间删除集合中的字段.通常,编译器不知道或关心调用站点特定方法调用实际上做了什么.
编译器是否优化(关闭)相同的
FieldByName调用?
不,不是的.
编译器不会查看函数调用内部以查看其中的内容.因此,它无法证明连续调用函数返回的值是相同的.同样,它无法证明该功能没有副作用.这些是正在考虑的优化的两个先决条件.
您需要自己执行优化,方法是显式添加和使用局部变量来存储单次调用返回的值FieldByName.
除了考虑性能之外,我认为使用局部变量来保持字段在语义上要好得多.这使读者清楚所有操作都在同一个字段上执行.仅凭这个原因足以说服我做出你所描述的改变.不要重复自己.
当我们处于代码审查模式时,您可能会重新考虑使用with.