编译器是否优化(关闭)相同的FieldByName调用?

时间:2014-06-27 12:37:50

标签: 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;

编译器(Delphi XE2,Win32 app)是否会优化方法2以使用temp var?两个FieldByNames非常接近,您甚至可以说嵌套

如果没有,我应该重写1.因为OnCalcFields经常执行。

顺便说一句。我知道Fields []和FieldByName(),或者在运行EOF循环时使用temp TField var,这里不是问题。

2 个答案:

答案 0 :(得分:7)

没有任何版本的Delphi编译器会做这样的事情。

这样的优化将要求编译器能够证明对FieldByName的两次调用总是给出相同的结果,并且目前没有规定将方法标记为确定性的。

注意,在理论上(如果实际上不太可能)两个调用很可能不会给出相同的结果,在这种情况下,例如如果另一个线程在第一次和第二次调用之间删除集合中的字段。通常,编译器不知道或关心调用站点特定方法调用实际上做了什么。

答案 1 :(得分:5)

  

编译器是否优化(关闭)相同的FieldByName次呼叫?

不,不。

编译器不查看函数调用内部以查看其中的内容。因此,它无法证明连续调用函数返回的值是相同的。同样,它无法证明该功能没有副作用。这些是正在考虑的优化的两个先决条件。

您需要自己执行优化,方法是显式添加和使用局部变量来存储单个调用返回FieldByName的值。


除了考虑性能之外,我认为使用局部变量来保持字段在语义上要好得多。这使读者清楚所有操作都在同一个字段上执行。仅凭这个原因足以说服我做出你所描述的改变。不要重复自己。

在我们处于代码审核模式时,您可能需要重新考虑使用with