Search code examples
delphidelphi-xe7

Compare Function result to multiple values


I'm redesigning some of my For-loops to run faster. Especially the ones that call functions to compare values with. I'm wondering if my basic Delphi knowledge is missing something really useful.

I have a lot of For-loops similar to this:

for i :=1 to 10000 do
  begin
    //---  Check if Condition for each Object (i) Property = Yes, Y or a Number  --- 
    if (fGetPropValue(i,'Condition')='Yes') Or (fGetPropValue(i,'Condition')='Y') Or (StrToIntDef(fGetPropValue(i,'Condition'),0)>0)
    then
      // code...

  end;

In this case function gets called 3 times, if result is different than Yes or Y. If it's Yes, it's only called once and skips the rest of calls.

I can use single call and store value to variable, like this:

for i :=1 to 10000 do
begin
  //---  Get Condition for each Object (i) Property   ---
  vCondition:=fGetPropValue(i,'Condition');
  //---  Check Condition = Yes, Y or a number  ---
  if (vCondition='Yes') Or (vCondition='Y') Or (StrtoIntDef(vCondition,0)>0)
  then
    // code...

end;

This is good, but what in case where I need to compare more complex, like:

for i :=1 to 10000 do
  begin

    if (fGetPropValue(i,'Condition')='Yes') Or (fGetPropValue(i,'Condition')='Y') Or (StrtoIntDef(fGetPropValue(i,'Condition'),0)>0) And
       (fGetPropValue(i,'Enabled')='Yes') Or (fGetPropValue(i,'Enabled')='Y') Or (StrtoIntDef(fGetPropValue(i,'Enabled'),0)>0) And
       (fGetPropValue(i,'Visible')='Yes') Or (fGetPropValue(i,'Visible')='Y') Or (StrtoIntDef(fGetPropValue(i,'Visible'),0)>0) And
       (fGetPropValue(i,'AllowAccess')='Yes') Or (fGetPropValue(i,'AllowAccess')='Y') Or (StrtoIntDef(fGetPropValue(i,'AllowAccess'),0)>0)
    then
      // code...

  end;

In this case if I introduce 4 variable and get all 4 values, I eliminate the speedy option if first logical comparison is true - without 4 variable it will not execute anymore calls.

Any way to redesign complex comparison?


Solution

  • You need to extract this into a function that you can re-use:

    function PropValueIsTrue(const PropValue: string): Boolean;
    begin
      Result := (PropValue='Yes') or (PropValue='Y') or (StrtoIntDef(PropValue,0)>0);
    end;
    

    Then your code becomes:

    if PropValueIsTrue(fGetPropValue(i,'Condition')) and
       PropValueIsTrue(fGetPropValue(i,'Enabled')) and
       PropValueIsTrue(fGetPropValue(i,'Visible')) and
       PropValueIsTrue(fGetPropValue(i,'AllowAccess')) then