Checking conditions [IF ... THEN ... ELSE] performance
09-14-2015, 06:24 PM (This post was last modified: 09-14-2015 08:17 PM by komame.)
Post: #1
 komame Member Posts: 50 Joined: Aug 2015
Checking conditions [IF ... THEN ... ELSE] performance
Hi,

I wonder if the checking conditions in HPPL are working properly.
It looks that all of the AND conditions are always executed even if first one returns false.
The same problem is for the OR conditions when the the first return true.

For example, if the expression is composed of three conditions and each of them is false then there is no need to check each of them. This is how languages C, C#, Java and other works.

HPPL seems to check every time all the conditions which may greatly slow down the program execution.

I did a little test for three conditions that each of them return false:

Example:
Code:
EXPORT TESTCONDITIONS() BEGIN   LOCAL a,b,x,t;   [[1,2,3],[4,5,6],[7,8,9]]▶a;   PRINT(); //first test   0▶b;   TICKS▶t;   FOR x FROM 1 TO 10000 DO     IF a[3,2]=7 AND a[1,1]=4 AND a[3,3]=8 THEN       b+1▶b;     END;   END;   PRINT(TICKS-t); //second test   0▶b;   TICKS▶t;   FOR x FROM 1 TO 10000 DO     IF a[3,2]=7 THEN       IF a[1,1]=4 THEN         IF a[3,3]=8 THEN           b+1▶b;         END;       END;     END;   END;   PRINT(TICKS-t); END;

When the program finishes there will be two measurements of time.
First is about 750 [ms] and the second id 360 [ms].
The first is test of 10000 times of three conditions using AND, the second is the same but use of implantation conditions. In the second case the program ran twice as fast.

The conditions can be very complex, eg. a complex function which returns true or false. Then check each of them is a large loss of performance.

I think HPPL would work like in other languages which would greatly accelerate programs execution.
09-14-2015, 07:21 PM
Post: #2 Joe Horn Senior Member Posts: 1,894 Joined: Dec 2013
RE: Checking conditions [IF ... THEN ... ELSE] performance
I verified your observation for both the infix AND operator, and the prefix and() function. All 4 of the following lines return the correct answer, but they all take 5 seconds to execute. The WAIT command in the second pair of lines should not be executed, but it is.

IF 1==1 AND WAIT(5)==5 THEN "True" ELSE "False" END --> "True"
IF and(1==1,WAIT(5)==5) THEN "True" ELSE "False" END --> "True"

IF 1==2 AND WAIT(5)==5 THEN "True" ELSE "False" END --> "False"
IF and(1==2,WAIT(5)==5) THEN "True" ELSE "False" END --> "False"

<0|ɸ|0>
-Joe-
09-14-2015, 07:36 PM (This post was last modified: 09-14-2015 07:39 PM by Tim Wessman.)
Post: #3 Tim Wessman Senior Member Posts: 2,283 Joined: Dec 2013
RE: Checking conditions [IF ... THEN ... ELSE] performance
I believe it is working as designed. I'm not sure if there is a generic way we can handle this due to PPL being both a math language, and program language though.

I've put it on the list to look at conditional short circuiting. If anything, I suspect the AND priority is what is impacting things here. Since it needs to be lower then other operators/functions it is most likely not evaluating till everything else has completed. Might not be a simple, general solution for this though...

TW

Although I work for HP, the views and opinions I post here are my own.
09-14-2015, 09:01 PM (This post was last modified: 09-14-2015 09:02 PM by komame.)
Post: #4
 komame Member Posts: 50 Joined: Aug 2015
RE: Checking conditions [IF ... THEN ... ELSE] performance
Generaly each condition has two parts: before the operator and after the operator.

In the case of the OR operator the first part is always checked and if it returns True the second part should be skipped.
In the case of the AND operator the first part is always checked and if it returns False the second part should be skipped.

Code:
local a=1,b=2,c=3,d=4; IF a==1 OR (b==2 AND c==4 OR d==4)  // the first part is [a==1] and the second part is the [(b==2 AND c==4 OR d==4)] the first part returns True so all after the OR operator should be skipped. IF a==2 AND (b==2 AND c==4 OR d==4)  // the first part is [a==2] and the second part is the [(b==2 AND c==4 OR d==4)] the first part returns False so all after the AND operator should be skipped.

I believe that all programming languages are working that way.
09-14-2015, 09:24 PM (This post was last modified: 09-14-2015 10:17 PM by primer.)
Post: #5
 primer Member Posts: 135 Joined: Sep 2015
RE: Checking conditions [IF ... THEN ... ELSE] performance
(09-14-2015 09:01 PM)komame Wrote:  I believe that all programming languages are working that way.
yes, indeed, and it's also very usefull to perform consistance checking,
for example
Code:
if( var!=0 AND a/var > b)
here the AND does not check condition a/var> b if var is null. here you avoid checking with inconsistant value (zero denominator)

I mean it's not only a question of performance.
Regards.
Post: #6
 roadrunner Senior Member Posts: 420 Joined: Jun 2015
RE: Checking conditions [IF ... THEN ... ELSE] performance
When time is an issue in any particular program the equivalent can be achieved with current PPL code using nested if's or the case function. Here's an example:

Code:
EXPORT eraseme1() BEGIN  if 1==1 then   if wait(5)==5 then "true"; end;  else "false"; end; END; export eraseme2() begin  if 1==2 then   if wait(5)==5 then "true"; end;  else "false"; end; end;

eraseme1() returns "true" and takes 5 seconds to run while eraseme2() returns "false" and takes a fraction of a second to run.

09-15-2015, 05:04 AM
Post: #7 Joe Horn Senior Member Posts: 1,894 Joined: Dec 2013
RE: Checking conditions [IF ... THEN ... ELSE] performance
(09-14-2015 09:01 PM)komame Wrote:  Generaly each condition has two parts: before the operator and after the operator.

In the case of the OR operator the first part is always checked and if it returns True the second part should be skipped.
In the case of the AND operator the first part is always checked and if it returns False the second part should be skipped. ...

I believe that all programming languages are working that way.

UBASIC both does and doesn't! It has two allowed syntaxes, infix and prefix, and they work differently:

Infix: A and B --> both expressions always get evaluated.

Prefix: and(A,B,C,...) --> evaluating from left to right, as soon as one of the arguments evaluates to 0, all subsequent arguments are skipped (unevaluated) and 0 is returned immediately.

Unfortunately HP-71 BASIC's "and" operator only has infix notation, and it always evaluates both expressions.

<0|ɸ|0>
-Joe-
09-15-2015, 05:25 AM
Post: #8
 cyrille de brébisson Senior Member Posts: 1,047 Joined: Dec 2013
RE: Checking conditions [IF ... THEN ... ELSE] performance
Hello,

You are correct. All parameters are evaluated FIRST and then the AND operation is 'calculated'.

a statement of the form
a AND b AND c
will be represented as an evaluation tree of the form (in LISP)
(AND a, AND(b, c))

It will cause a to be evaluated, then b, then c, then the b AND c will be calculated, and finally the a AND result of AND(b,c)...
You can check that by replacing a, b and c by function call that print something on the screen and looking at the print order.

This difears from C type programming languages which do have OR/AND operator short circuiting.

This feels correct for math operation, but it is true that it is not optimal from a programming performance point of view.

Cyrille

Although I work for the HP calculator group, the views and opinions I post here are my own. I do not speak for HP.
09-15-2015, 09:42 AM
Post: #9
 StephenG1CMZ Senior Member Posts: 945 Joined: May 2015
RE: Checking conditions [IF ... THEN ... ELSE] performance
I tried a little code like the excel function andlist, to see if having the functions in a list rather than separately might help: it doesn't.

Then I tried implementing the execution of one of two functions passed as parameters:
If choice then fun1 else fun2 end if.
Again, it seems both fun1 and fun2 are executed simply by being parameters.

Am I understanding this correctly?

Code:
    RR(V)  BEGIN   IF V THEN    PRINT("TRUE");   ELSE    PRINT("FALSE");   END;  END;    FLS()  BEGIN   PRINT("FLS");  RETURN 0;  END;  TRU()  BEGIN   PRINT("TRU");   RETURN 1;   END;    ZAND(A,B)  BEGIN   0▶R;   IF A  THEN    IF B THEN      PRINT("WHY");      1▶R;    END;   END;   PRINT("R"+R);  END;  ZANDLST(LL)  BEGIN   LOCAL SOFAR:=1;   LOCAL I:=1;   PRINT("ZANDLST:");   WHILE I≤SIZE(LL)  AND SOFAR DO     SOFAR:=LL(I);     PRINT(I+","+SOFAR);   END;   RR(SOFAR);   RETURN SOFAR;   END;  CHS(CHOICE,A,B)  BEGIN   IF CHOICE THEN    PRINT("A CHOSEN");    A();   ELSE    PRINT("B CHOSEN");    B();   END;  END; EXPORT ZANDTRY() BEGIN  PRINT();  ZAND(FLS(),TRU());  //PRINT("ZL");  //ZANDLST({FLS(),TRU()});  PRINT("CHOICE:");  CHS(1,FLS(),TRU());    WAIT; END;

Stephen Lewkowicz (G1CMZ)
 « Next Oldest | Next Newest »

User(s) browsing this thread: 1 Guest(s)